From a173639197cf8b4e279b3ba50917bc13989abde4 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 6 Jan 2023 17:21:34 +0100 Subject: [PATCH 001/159] project: Update DOTS dependency to 1.0. --- package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/package.json b/package.json index 4ea332a99..02d413fb2 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,8 @@ "unity": "2021.3", "unityRelease": "0f1", "dependencies": { - "com.unity.burst": "1.6.5", - "com.unity.entities": "0.17.0-preview.42", + "com.unity.entities": "1.0-pre.15", "com.unity.formats.fbx": "4.1.2", - "com.unity.jobs": "0.8.0-preview.23", - "com.unity.mathematics": "1.2.5", "com.unity.inputsystem": "1.3.0", "com.unity.ugui": "1.0.0", "com.unity.test-framework": "1.1.31" From 027275548a1100a3624edb9d8de080ba0d642a72 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 6 Jan 2023 17:22:23 +0100 Subject: [PATCH 002/159] dots: Fix system access. --- .../Physics/Collision/PhysicsMaterialData.cs | 4 ++-- .../SystemGroup/SimulateBuildSystem.cs | 2 +- .../SystemGroup/SimulateCycleSystemGroup.cs | 20 +++++++++---------- .../VPT/PhysicsMaterialAsset.cs | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs index 11b50b176..316dbabee 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs @@ -25,9 +25,9 @@ public struct PhysicsMaterialData : IComponentData public float ElasticityFalloff; public float Friction; public float ScatterAngleRad; - public FixedListFloat512 ElasticityOverVelocityLUT; + public FixedList512Bytes ElasticityOverVelocityLUT; public bool UseElasticityOverVelocity; - public FixedListFloat512 FrictionOverVelocityLUT; + public FixedList512Bytes FrictionOverVelocityLUT; public bool UseFrictionOverVelocity; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs index a31837c2d..a976fd341 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs @@ -44,7 +44,7 @@ protected override void OnUpdate() return; } var ltw = _baseTransform; - Entities.WithName("SimulateBuildJob").ForEach((ref Translation translation, ref BallData ball) => { + Entities.WithName("SimulateBuildJob").ForEach((ref BallData ball) => { ball.Position = math.transform(math.inverse(ltw), math.transform(ltw, float3.zero)); }).Run(); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs index b88acb386..b76e92dda 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs @@ -76,16 +76,16 @@ protected override void OnCreate() _flipperDataQuery = EntityManager.CreateEntityQuery(ComponentType.ReadOnly(), ComponentType.ReadOnly()); _collisionEventDataQuery = EntityManager.CreateEntityQuery(ComponentType.ReadOnly()); - _simulationSystemGroup = World.GetExistingSystem(); - _staticBroadPhaseSystem = World.GetOrCreateSystem(); - _dynamicBroadPhaseSystem = World.GetOrCreateSystem(); - _staticNarrowPhaseSystem = World.GetOrCreateSystem(); - _dynamicNarrowPhaseSystem = World.GetOrCreateSystem(); - _displacementSystemGroup = World.GetOrCreateSystem(); - _staticCollisionSystem = World.GetOrCreateSystem(); - _dynamicCollisionSystem = World.GetOrCreateSystem(); - _contactSystem = World.GetOrCreateSystem(); - _ballSpinHackSystem = World.GetOrCreateSystem(); + _simulationSystemGroup = World.GetExistingSystemManaged(); + _staticBroadPhaseSystem = World.GetExistingSystemManaged(); + _dynamicBroadPhaseSystem = World.GetExistingSystemManaged(); + _staticNarrowPhaseSystem = World.GetExistingSystemManaged(); + _dynamicNarrowPhaseSystem = World.GetExistingSystemManaged(); + _displacementSystemGroup = World.GetExistingSystemManaged(); + _staticCollisionSystem = World.GetExistingSystemManaged(); + _dynamicCollisionSystem = World.GetExistingSystemManaged(); + _contactSystem = World.GetExistingSystemManaged(); + _ballSpinHackSystem = World.GetExistingSystemManaged(); _systemsToUpdate.Add(_staticBroadPhaseSystem); _systemsToUpdate.Add(_dynamicBroadPhaseSystem); _systemsToUpdate.Add(_staticNarrowPhaseSystem); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/PhysicsMaterialAsset.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/PhysicsMaterialAsset.cs index 9ae40048b..2b28322b1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/PhysicsMaterialAsset.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/PhysicsMaterialAsset.cs @@ -38,11 +38,11 @@ public class PhysicsMaterialAsset : ScriptableObject public float ElasticityFalloff; public AnimationCurve ElasticityOverVelocity; public bool UseElasticictyOverVelocity; - public FixedListFloat512 ElasticityOverVelocityLUT; + public FixedList512Bytes ElasticityOverVelocityLUT; public float Friction; public AnimationCurve FrictionOverVelocity; public bool UseFrictionOverVelocity; - public FixedListFloat512 FrictionOverVelocityLUT; + public FixedList512Bytes FrictionOverVelocityLUT; // public AnimationCurve FrictionOverAngularMomentum; public float ScatterAngle; From 2c91712b952cd687dc0e544549659e61ff08de95 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 6 Jan 2023 17:22:54 +0100 Subject: [PATCH 003/159] dots: Add flipper baker. --- .../VPT/Flipper/FlipperBaker.cs | 149 ++++++++++++++++++ .../VPT/Flipper/FlipperBaker.cs.meta | 3 + .../VPT/Flipper/FlipperComponent.cs | 132 +--------------- .../VisualPinball.Unity/VPT/ItemBaker.cs | 31 ++++ .../VisualPinball.Unity/VPT/ItemBaker.cs.meta | 3 + .../VPT/MainRenderableComponent.cs | 2 +- 6 files changed, 193 insertions(+), 127 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs new file mode 100644 index 000000000..25bb9d107 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs @@ -0,0 +1,149 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using Unity.Collections; +using Unity.Entities; +using VisualPinball.Engine.Math; +using VisualPinball.Engine.VPT.Flipper; +using VisualPinball.Engine.VPT.Trigger; + +namespace VisualPinball.Unity +{ + public class FlipperBaker : ItemBaker + { + public override void Bake(FlipperComponent authoring) + { + base.Bake(authoring); + + var player = authoring.transform.GetComponentInParent(); + var colliderComponent = authoring.gameObject.GetComponent(); + + // collision + if (colliderComponent) { + + // vpx physics + var d = authoring.GetMaterialData(colliderComponent); + AddComponent(d); + AddComponent(authoring.GetMovementData(d)); + AddComponent(FlipperComponent.GetVelocityData(d)); + AddComponent(authoring.GetHitData()); + AddComponent(authoring.GetFlipperTricksData(colliderComponent, d)); + AddComponent(new SolenoidStateData { Value = false }); + + // flipper correction (nFozzy) + if (colliderComponent.FlipperCorrection) { + SetupFlipperCorrection(authoring, player, colliderComponent); + } + } + + // register + player.RegisterFlipper(authoring, GetEntity()); + } + + private void SetupFlipperCorrection(FlipperComponent authoring, Player player, FlipperColliderComponent colliderComponent) + { + var fc = colliderComponent.FlipperCorrection; + + // create trigger + var triggerData = CreateCorrectionTriggerData(authoring); + var triggerEntity = CreateAdditionalEntity(); + AddComponent(triggerEntity, new TriggerStaticData()); + player.RegisterTrigger(triggerData, triggerEntity, authoring.gameObject); + + using (var builder = new BlobBuilder(Allocator.Temp)) { + + ref var root = ref builder.ConstructRoot(); + root.FlipperEntity = GetEntity(); + root.TimeDelayMs = fc.TimeThresholdMs; + + // Discretize the curves + var polarities = builder.Allocate(ref root.Polarities, fc.PolaritiesCurveSlicingCount + 1); + if (fc.Polarities != null) + { + var curve = fc.Polarities; + float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.PolaritiesCurveSlicingCount; + int i = 0; + for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) + { + polarities[i].x = t; + polarities[i++].y = curve.Evaluate(t); + } + } + else + { + for (int i = 0; i < fc.PolaritiesCurveSlicingCount + 1; i++) + { + polarities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; + polarities[i].y = 0F; + } + } + + var velocities = builder.Allocate(ref root.Velocities, fc.VelocitiesCurveSlicingCount + 1); + if (fc.Velocities != null) + { + var curve = fc.Velocities; + float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.VelocitiesCurveSlicingCount; + int i = 0; + for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) + { + velocities[i].x = t; + velocities[i++].y = curve.Evaluate(t); + } + } + else + { + for (int i = 0; i < fc.VelocitiesCurveSlicingCount + 1; i++) + { + velocities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; + velocities[i].y = 1F; + } + } + + var blobAssetRef = builder.CreateBlobAssetReference(Allocator.Persistent); + + // add correction data + AddComponent(triggerEntity, new FlipperCorrectionData { + Value = blobAssetRef + }); + } + } + + public TriggerData CreateCorrectionTriggerData(FlipperComponent authoring) + { + // Get table reference + var ta = GetComponentInParent(); + if (ta != null) { + + var localPos = authoring.transform.localPosition; + var data = new TriggerData(authoring.name + " (Correction Trigger)", localPos.x, localPos.y); + var poly = authoring.GetEnclosingPolygon(23, 12); + data.DragPoints = new DragPointData[poly.Count]; + data.IsLocked = true; + data.HitHeight = 150F; // nFozzy's recommendation, but I think 50 should be ok + + for (var i = 0; i < poly.Count; i++) { + // Poly points are expressed in flipper's frame: transpose to Table's frame as this is the basis uses for drag points + var p = ta.transform.InverseTransformPoint(authoring.transform.TransformPoint(poly[i])); + data.DragPoints[poly.Count - i - 1] = new DragPointData(p.x, p.y); + } + return data; + } + throw new InvalidOperationException("Cannot create correction trigger for flipper outside of the table hierarchy."); + } + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs.meta new file mode 100644 index 000000000..45bdaceb2 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e5d44d70389a4e5a88256364ec7512cf +timeCreated: 1673020322 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index e03fc4839..5ddcdfb84 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -41,7 +41,7 @@ namespace VisualPinball.Unity [HelpURL("https://docs.visualpinball.org/creators-guide/manual/mechanisms/flippers.html")] public class FlipperComponent : MainRenderableComponent, IFlipperData, ISwitchDeviceComponent, ICoilDeviceComponent, IOnSurfaceComponent, - IRotatableComponent, IConvertGameObjectToEntity + IRotatableComponent { #region Data @@ -201,35 +201,6 @@ public float2 RotatedPosition { #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - var player = transform.GetComponentInParent(); - var colliderComponent = gameObject.GetComponent(); - - // collision - if (colliderComponent) { - - // vpx physics - var d = GetMaterialData(colliderComponent); - dstManager.AddComponentData(entity, d); - dstManager.AddComponentData(entity, GetMovementData(d)); - dstManager.AddComponentData(entity, GetVelocityData(d)); - dstManager.AddComponentData(entity, GetHitData()); - dstManager.AddComponentData(entity, GetFlipperTricksData(colliderComponent, d)); - dstManager.AddComponentData(entity, new SolenoidStateData { Value = false }); - - // flipper correction (nFozzy) - if (colliderComponent.FlipperCorrection) { - SetupFlipperCorrection(entity, dstManager, player, colliderComponent); - } - } - - // register - player.RegisterFlipper(this, entity); - } - public override IEnumerable SetData(FlipperData data) { var updatedComponents = new List { this }; @@ -435,74 +406,6 @@ protected void OnDrawGizmosSelected() private bool IsLeft => EndAngle < _startAngle; - private void SetupFlipperCorrection(Entity entity, EntityManager dstManager, Player player, FlipperColliderComponent colliderComponent) - { - var fc = colliderComponent.FlipperCorrection; - - // create trigger - var triggerData = CreateCorrectionTriggerData(); - var triggerEntity = dstManager.CreateEntity(typeof(TriggerStaticData)); - dstManager.AddComponentData(triggerEntity, new TriggerStaticData()); - player.RegisterTrigger(triggerData, triggerEntity, gameObject); - - using (var builder = new BlobBuilder(Allocator.Temp)) { - - ref var root = ref builder.ConstructRoot(); - root.FlipperEntity = entity; - root.TimeDelayMs = fc.TimeThresholdMs; - - // Discretize the curves - var polarities = builder.Allocate(ref root.Polarities, fc.PolaritiesCurveSlicingCount + 1); - if (fc.Polarities != null) - { - var curve = fc.Polarities; - float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.PolaritiesCurveSlicingCount; - int i = 0; - for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) - { - polarities[i].x = t; - polarities[i++].y = curve.Evaluate(t); - } - } - else - { - for (int i = 0; i < fc.PolaritiesCurveSlicingCount + 1; i++) - { - polarities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; - polarities[i].y = 0F; - } - } - - var velocities = builder.Allocate(ref root.Velocities, fc.VelocitiesCurveSlicingCount + 1); - if (fc.Velocities != null) - { - var curve = fc.Velocities; - float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.VelocitiesCurveSlicingCount; - int i = 0; - for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) - { - velocities[i].x = t; - velocities[i++].y = curve.Evaluate(t); - } - } - else - { - for (int i = 0; i < fc.VelocitiesCurveSlicingCount + 1; i++) - { - velocities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; - velocities[i].y = 1F; - } - } - - var blobAssetRef = builder.CreateBlobAssetReference(Allocator.Persistent); - - // add correction data - dstManager.AddComponentData(triggerEntity, new FlipperCorrectionData { - Value = blobAssetRef - }); - } - } - //! Add a circle arc on a given polygon (used for enclosing poygon) public static void AddPolyArc(List poly, Vector3 center, float radius, float angleFrom, float angleTo, float stepSize = 1F, float height = 0f) { @@ -571,29 +474,6 @@ public List GetEnclosingPolygon(float margin = 0.0F, float stepSize = 5 return ret; } - public TriggerData CreateCorrectionTriggerData() - { - // Get table reference - var ta = GetComponentInParent(); - if (ta != null) { - - var localPos = transform.localPosition; - var data = new TriggerData(name + " (Correction Trigger)", localPos.x, localPos.y); - var poly = GetEnclosingPolygon(23, 12); - data.DragPoints = new DragPointData[poly.Count]; - data.IsLocked = true; - data.HitHeight = 150F; // nFozzy's recommendation, but I think 50 should be ok - - for (var i = 0; i < poly.Count; i++) { - // Poly points are expressed in flipper's frame: transpose to Table's frame as this is the basis uses for drag points - var p = ta.transform.InverseTransformPoint(transform.TransformPoint(poly[i])); - data.DragPoints[poly.Count - i - 1] = new DragPointData(p.x, p.y); - } - return data; - } - throw new InvalidOperationException("Cannot create correction trigger for flipper outside of the table hierarchy."); - } - #endregion #region Runtime @@ -612,7 +492,7 @@ private void Start() #region DOTS Data - private FlipperTricksData GetFlipperTricksData(FlipperColliderComponent colliderComponent, FlipperStaticData staticData) + internal FlipperTricksData GetFlipperTricksData(FlipperColliderComponent colliderComponent, FlipperStaticData staticData) { return new FlipperTricksData { @@ -646,7 +526,7 @@ private FlipperTricksData GetFlipperTricksData(FlipperColliderComponent collider }; } - private FlipperStaticData GetMaterialData(FlipperColliderComponent colliderComponent) + internal FlipperStaticData GetMaterialData(FlipperColliderComponent colliderComponent) { float flipperRadius; if (FlipperRadiusMin > 0 && FlipperRadiusMax > FlipperRadiusMin) { @@ -687,7 +567,7 @@ private FlipperStaticData GetMaterialData(FlipperColliderComponent colliderCompo }; } - private FlipperMovementData GetMovementData(FlipperStaticData d) + internal FlipperMovementData GetMovementData(FlipperStaticData d) { // store flipper base rotation without starting angle var baseRotation = math.normalize(math.mul( @@ -702,7 +582,7 @@ private FlipperMovementData GetMovementData(FlipperStaticData d) }; } - private static FlipperVelocityData GetVelocityData(FlipperStaticData d) + internal static FlipperVelocityData GetVelocityData(FlipperStaticData d) { return new FlipperVelocityData { AngularAcceleration = 0f, @@ -713,7 +593,7 @@ private static FlipperVelocityData GetVelocityData(FlipperStaticData d) }; } - private FlipperHitData GetHitData() + internal FlipperHitData GetHitData() { var ratio = (math.max(_baseRadius, 0.01f) - math.max(_endRadius, 0.01f)) / math.max(FlipperRadiusMax, 0.01f); var zeroAngNorm = new float2( diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs new file mode 100644 index 000000000..b61b40443 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs @@ -0,0 +1,31 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Entities; +using VisualPinball.Engine.VPT; + +namespace VisualPinball.Unity +{ + public abstract class ItemBaker : Baker + where T : MainRenderableComponent + where TData : ItemData + { + public override void Bake(T authoring) + { + authoring.Entity = GetEntity(); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs.meta new file mode 100644 index 000000000..1589fc76d --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c70518a0b50849d7a4d5bfa6615ffa93 +timeCreated: 1673021439 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs index 014bd4175..a36427edf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs @@ -25,7 +25,7 @@ namespace VisualPinball.Unity { - public abstract class MainRenderableComponent : MainComponent, + public abstract class MainRenderableComponent : MainComponent, IMainRenderableComponent, IOnPlayfieldComponent where TData : ItemData { From e35a6257702c0b8972491b4296ce70ba0c0f2958 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 6 Jan 2023 17:30:06 +0100 Subject: [PATCH 004/159] dots: Add bumper baker --- .../VPT/Bumper/BumperBaker.cs | 73 +++++++++++++++++++ .../VPT/Bumper/BumperBaker.cs.meta | 3 + .../VPT/Bumper/BumperComponent.cs | 52 +------------ .../VPT/Flipper/FlipperComponent.cs | 5 -- 4 files changed, 77 insertions(+), 56 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs new file mode 100644 index 000000000..616f8faa4 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs @@ -0,0 +1,73 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Mathematics; +using VisualPinball.Engine.VPT.Bumper; + +namespace VisualPinball.Unity +{ + public class BumperBaker : ItemBaker + { + public override void Bake(BumperComponent authoring) + { + base.Bake(authoring); + + // physics collision data + var collComponent = GetComponentInChildren(); + if (collComponent) { + AddComponent(new BumperStaticData { + Force = collComponent.Force, + HitEvent = collComponent.HitEvent, + Threshold = collComponent.Threshold + }); + } + + // skirt animation data + if (GetComponentInChildren()) { + AddComponent(new BumperSkirtAnimationData { + BallPosition = default, + AnimationCounter = 0f, + DoAnimate = false, + DoUpdate = false, + EnableAnimation = true, + Rotation = new float2(0, 0), + Center = authoring.Position + }); + } + + // ring animation data + var ringAnimComponent = GetComponentInChildren(); + if (ringAnimComponent) { + AddComponent(new BumperRingAnimationData { + + // dynamic + IsHit = false, + Offset = 0, + AnimateDown = false, + DoAnimate = false, + + // static + DropOffset = ringAnimComponent.RingDropOffset, + HeightScale = authoring.HeightScale, + Speed = ringAnimComponent.RingSpeed, + }); + } + + // register at player + GetComponentInParent().RegisterBumper(authoring, GetEntity()); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs.meta new file mode 100644 index 000000000..f2dd7c3af --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 209394c940da47d28fa72de81c7330f4 +timeCreated: 1673022285 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs index 326c34b6f..a0c13a4e3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs @@ -23,7 +23,6 @@ using System; using System.Collections.Generic; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Game.Engines; @@ -35,7 +34,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Bumper")] public class BumperComponent : MainRenderableComponent, - ISwitchDeviceComponent, ICoilDeviceComponent, IOnSurfaceComponent, IConvertGameObjectToEntity + ISwitchDeviceComponent, ICoilDeviceComponent, IOnSurfaceComponent { #region Data @@ -133,55 +132,6 @@ public override void UpdateTransforms() #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - // physics collision data - var collComponent = GetComponentInChildren(); - if (collComponent) { - dstManager.AddComponentData(entity, new BumperStaticData { - Force = collComponent.Force, - HitEvent = collComponent.HitEvent, - Threshold = collComponent.Threshold - }); - } - - // skirt animation data - if (GetComponentInChildren()) { - dstManager.AddComponentData(entity, new BumperSkirtAnimationData { - BallPosition = default, - AnimationCounter = 0f, - DoAnimate = false, - DoUpdate = false, - EnableAnimation = true, - Rotation = new float2(0, 0), - Center = Position - }); - } - - // ring animation data - var ringAnimComponent = GetComponentInChildren(); - if (ringAnimComponent) { - dstManager.AddComponentData(entity, new BumperRingAnimationData { - - // dynamic - IsHit = false, - Offset = 0, - AnimateDown = false, - DoAnimate = false, - - // static - DropOffset = ringAnimComponent.RingDropOffset, - HeightScale = HeightScale, - Speed = ringAnimComponent.RingSpeed, - }); - } - - // register at player - GetComponentInParent().RegisterBumper(this, entity); - } - public override IEnumerable SetData(BumperData data) { var updatedComponents = new List { this }; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index 5ddcdfb84..f1a7f6f31 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -23,17 +23,12 @@ using System; using System.Collections.Generic; -using Unity.Collections; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Game.Engines; -using VisualPinball.Engine.Math; using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.Flipper; using VisualPinball.Engine.VPT.Table; -using VisualPinball.Engine.VPT.Trigger; -using Color = UnityEngine.Color; namespace VisualPinball.Unity { From 98988084f49b389f478938a5f0d1064e9b23bb06 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 6 Jan 2023 17:36:12 +0100 Subject: [PATCH 005/159] dots: Add gate baker. --- .../VPT/Flipper/FlipperBaker.cs | 4 +- .../VisualPinball.Unity/VPT/Gate/GateBaker.cs | 60 +++++++++++++++++++ .../VPT/Gate/GateBaker.cs.meta | 3 + .../VPT/Gate/GateComponent.cs | 41 ++----------- 4 files changed, 69 insertions(+), 39 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs index 25bb9d107..09151ad5e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs @@ -29,8 +29,8 @@ public override void Bake(FlipperComponent authoring) { base.Bake(authoring); - var player = authoring.transform.GetComponentInParent(); - var colliderComponent = authoring.gameObject.GetComponent(); + var player = GetComponentInParent(); + var colliderComponent = GetComponent(); // collision if (colliderComponent) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs new file mode 100644 index 000000000..67563a1ea --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs @@ -0,0 +1,60 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Mathematics; +using UnityEngine.UIElements; +using VisualPinball.Engine.Common; +using VisualPinball.Engine.VPT.Gate; + +namespace VisualPinball.Unity +{ + public class GateBaker : ItemBaker + { + public override void Bake(GateComponent authoring) + { + base.Bake(authoring); + + // collision + var colliderComponent = GetComponent(); + if (colliderComponent) { + + AddComponent(new GateStaticData { + AngleMin = math.radians(colliderComponent._angleMin), + AngleMax = math.radians(colliderComponent._angleMax), + Height = authoring.Position.z, + Damping = math.pow(colliderComponent.Damping, (float)PhysicsConstants.PhysFactor), + GravityFactor = colliderComponent.GravityFactor, + TwoWay = colliderComponent.TwoWay, + }); + + // movement data + if (GetComponentInChildren()) { + AddComponent(new GateMovementData { + Angle = math.radians(colliderComponent._angleMin), + AngleSpeed = 0, + ForcedMove = false, + IsOpen = false, + HitDirection = false + }); + } + } + + // register + GetComponentInParent().RegisterGate(authoring, GetEntity()); + + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs.meta new file mode 100644 index 000000000..da4e328ec --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 940446727b09426b908921cde61994f0 +timeCreated: 1673022636 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs index 9c8eb969d..f1241c426 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs @@ -23,10 +23,10 @@ using System; using System.Collections.Generic; -using Unity.Entities; +using System.IO; using Unity.Mathematics; +using UnityEditor; using UnityEngine; -using VisualPinball.Engine.Common; using VisualPinball.Engine.Game.Engines; using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.Gate; @@ -36,7 +36,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Gate")] public class GateComponent : MainRenderableComponent, - IGateData, ISwitchDeviceComponent, IOnSurfaceComponent, IConvertGameObjectToEntity + IGateData, ISwitchDeviceComponent, IOnSurfaceComponent { #region Data @@ -141,39 +141,6 @@ public override void UpdateTransforms() #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - // collision - var colliderComponent = gameObject.GetComponent(); - if (colliderComponent) { - - dstManager.AddComponentData(entity, new GateStaticData { - AngleMin = math.radians(colliderComponent._angleMin), - AngleMax = math.radians(colliderComponent._angleMax), - Height = Position.z, - Damping = math.pow(colliderComponent.Damping, (float)PhysicsConstants.PhysFactor), - GravityFactor = colliderComponent.GravityFactor, - TwoWay = colliderComponent.TwoWay, - }); - - // movement data - if (GetComponentInChildren()) { - dstManager.AddComponentData(entity, new GateMovementData { - Angle = math.radians(colliderComponent._angleMin), - AngleSpeed = 0, - ForcedMove = false, - IsOpen = false, - HitDirection = false - }); - } - } - - // register - transform.GetComponentInParent().RegisterGate(this, entity); - } - public override IEnumerable SetData(GateData data) { var updatedComponents = new List { this }; @@ -219,7 +186,7 @@ public override IEnumerable SetReferencedData(GateData data, Tabl break; case WireObjectName: #if UNITY_EDITOR - _meshName = System.IO.Path.GetFileNameWithoutExtension(UnityEditor.AssetDatabase.GetAssetPath(mf.sharedMesh)); + _meshName = Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(mf.sharedMesh)); #endif mf.gameObject.SetActive(data.IsVisible); break; From 6f3cd3e9d73f8b99153b4aae733cac73c3c3a0c3 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 6 Jan 2023 17:43:13 +0100 Subject: [PATCH 006/159] dots: Add hit target bakers. --- .../VPT/HitTarget/DropTargetBaker.cs | 48 +++++++++++++++++++ .../VPT/HitTarget/DropTargetBaker.cs.meta | 3 ++ .../VPT/HitTarget/DropTargetComponent.cs | 21 +------- .../VPT/HitTarget/HitTargetBaker.cs | 45 +++++++++++++++++ .../VPT/HitTarget/HitTargetBaker.cs.meta | 3 ++ .../VPT/HitTarget/HitTargetComponent.cs | 25 +--------- 6 files changed, 101 insertions(+), 44 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs new file mode 100644 index 000000000..943962082 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs @@ -0,0 +1,48 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.VPT.HitTarget; + +namespace VisualPinball.Unity +{ + public class DropTargetBaker : ItemBaker + { + public override void Bake(DropTargetComponent authoring) + { + base.Bake(authoring); + + var colliderComponent = GetComponent(); + var animationComponent = GetComponentInChildren(); + if (colliderComponent && animationComponent) { + + AddComponent(new DropTargetStaticData { + Speed = animationComponent.Speed, + RaiseDelay = animationComponent.RaiseDelay, + UseHitEvent = colliderComponent.UseHitEvent, + }); + + AddComponent(new DropTargetAnimationData { + IsDropped = animationComponent.IsDropped, + MoveDown = !animationComponent.IsDropped, + ZOffset = animationComponent.IsDropped ? -DropTargetAnimationData.DropTargetLimit : 0f + }); + } + + // register + GetComponentInParent().RegisterDropTarget(authoring, GetEntity()); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs.meta new file mode 100644 index 000000000..66cb60131 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a120608c3b854e1f9a5342886f77b6d3 +timeCreated: 1673023180 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs index 2535133de..83c2c47c3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs @@ -27,7 +27,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Drop Target")] - public class DropTargetComponent : TargetComponent, IConvertGameObjectToEntity + public class DropTargetComponent : TargetComponent { public override bool IsLegacy { get { @@ -49,25 +49,6 @@ public void Convert(Entity entity, EntityManager dstManager, GameObjectConversio { Convert(entity, dstManager); - var colliderComponent = GetComponent(); - var animationComponent = GetComponentInChildren(); - if (colliderComponent && animationComponent) { - - dstManager.AddComponentData(entity, new DropTargetStaticData { - Speed = animationComponent.Speed, - RaiseDelay = animationComponent.RaiseDelay, - UseHitEvent = colliderComponent.UseHitEvent, - }); - - dstManager.AddComponentData(entity, new DropTargetAnimationData { - IsDropped = animationComponent.IsDropped, - MoveDown = !animationComponent.IsDropped, - ZOffset = animationComponent.IsDropped ? -DropTargetAnimationData.DropTargetLimit : 0f - }); - } - - // register - transform.GetComponentInParent().RegisterDropTarget(this, entity); } public override IEnumerable SetData(HitTargetData data) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs new file mode 100644 index 000000000..16525ff5c --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs @@ -0,0 +1,45 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.VPT.HitTarget; + +namespace VisualPinball.Unity +{ + public class HitTargetBaker : ItemBaker + { + public override void Bake(HitTargetComponent authoring) + { + base.Bake(authoring); + + var hitTargetColliderComponent = GetComponent(); + var hitTargetAnimationComponent = GetComponentInChildren(); + if (hitTargetColliderComponent && hitTargetAnimationComponent) { + + AddComponent(new HitTargetStaticData { + Speed = hitTargetAnimationComponent.Speed, + MaxAngle = hitTargetAnimationComponent.MaxAngle, + }); + + AddComponent(new HitTargetAnimationData { + MoveDirection = true, + }); + } + + // register + GetComponentInParent().RegisterHitTarget(authoring, GetEntity()); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs.meta new file mode 100644 index 000000000..e4d69bb6b --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c0e158fb147149a88110ec2238763c1a +timeCreated: 1673023020 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs index 576a51bdc..397559167 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.HitTarget; using VisualPinball.Engine.VPT.Table; @@ -25,7 +24,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Hit Target")] - public class HitTargetComponent : TargetComponent, IConvertGameObjectToEntity + public class HitTargetComponent : TargetComponent { protected override float ZOffset => 0; @@ -33,28 +32,6 @@ public class HitTargetComponent : TargetComponent, IConvertGameObjectToEntity #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - var hitTargetColliderComponent = GetComponent(); - var hitTargetAnimationComponent = GetComponentInChildren(); - if (hitTargetColliderComponent && hitTargetAnimationComponent) { - - dstManager.AddComponentData(entity, new HitTargetStaticData { - Speed = hitTargetAnimationComponent.Speed, - MaxAngle = hitTargetAnimationComponent.MaxAngle, - }); - - dstManager.AddComponentData(entity, new HitTargetAnimationData { - MoveDirection = true, - }); - } - - // register - transform.GetComponentInParent().RegisterHitTarget(this, entity); - } - public override IEnumerable SetData(HitTargetData data) { var updatedComponents = base.SetData(data).ToList(); From a2c2f4e57b7ae8c2564ae72ba4a073098793f81f Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 6 Jan 2023 17:47:49 +0100 Subject: [PATCH 007/159] dots: Add kicker baker. --- .../VPT/HitTarget/DropTargetComponent.cs | 7 -- .../VPT/Kicker/KickerBaker.cs | 68 +++++++++++++++++++ .../VPT/Kicker/KickerBaker.cs.meta | 3 + .../VPT/Kicker/KickerComponent.cs | 53 ++------------- 4 files changed, 76 insertions(+), 55 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs index 83c2c47c3..20f778cef 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs @@ -19,7 +19,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.HitTarget; using VisualPinball.Engine.VPT.Table; @@ -45,12 +44,6 @@ protected override float ZOffset { #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - } - public override IEnumerable SetData(HitTargetData data) { var updatedComponents = base.SetData(data).ToList(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs new file mode 100644 index 000000000..c9702dcd0 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs @@ -0,0 +1,68 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Entities; +using VisualPinball.Engine.VPT.Kicker; + +namespace VisualPinball.Unity +{ + public class KickerBaker : ItemBaker + { + public override void Bake(KickerComponent authoring) + { + base.Bake(authoring); + + // collision + var colliderComponent = GetComponent(); + if (colliderComponent) { + AddComponent(new KickerStaticData { + Center = authoring.Position, + FallIn = colliderComponent.FallIn, + FallThrough = colliderComponent.FallThrough, + HitAccuracy = colliderComponent.HitAccuracy, + Scatter = colliderComponent.Scatter, + LegacyMode = true, // todo colliderComponent.LegacyMode, + ZLow = authoring.Surface?.Height(authoring.Position) ?? authoring.PlayfieldHeight + }); + + AddComponent(new KickerCollisionData { + BallEntity = Entity.Null, + LastCapturedBallEntity = Entity.Null + }); + + // if (!Data.LegacyMode) { + // // todo currently we don't allow non-legacy mode + // using (var blobBuilder = new BlobBuilder(Allocator.Temp)) { + // ref var blobAsset = ref blobBuilder.ConstructRoot(); + // var vertices = blobBuilder.Allocate(ref blobAsset.Vertices, Item.KickerHit.HitMesh.Length); + // var normals = blobBuilder.Allocate(ref blobAsset.Normals, Item.KickerHit.HitMesh.Length); + // for (var i = 0; i < Item.KickerHit.HitMesh.Length; i++) { + // var v = Item.KickerHit.HitMesh[i]; + // vertices[i] = new KickerMeshVertex { Vertex = v.ToUnityFloat3() }; + // normals[i] = new KickerMeshVertex { Vertex = new float3(KickerHitMesh.Vertices[i].Nx, KickerHitMesh.Vertices[i].Ny, KickerHitMesh.Vertices[i].Nz) }; + // } + // + // var blobAssetReference = blobBuilder.CreateBlobAssetReference(Allocator.Persistent); + // dstManager.AddComponentData(entity, new ColliderMeshData { Value = blobAssetReference }); + // } + // } + } + + // register + GetComponentInParent().RegisterKicker(authoring, GetEntity()); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs.meta new file mode 100644 index 000000000..ecb64cac8 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bc1c67453a004de8b0c4308582274ac5 +timeCreated: 1673023434 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs index de586fab7..c0b1a5811 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs @@ -23,9 +23,10 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; -using Unity.Entities; using Unity.Mathematics; +using UnityEditor; using UnityEngine; using VisualPinball.Engine.Game; using VisualPinball.Engine.Game.Engines; @@ -39,7 +40,7 @@ namespace VisualPinball.Unity [AddComponentMenu("Visual Pinball/Game Item/Kicker")] public class KickerComponent : MainRenderableComponent, ICoilDeviceComponent, ITriggerComponent, IBallCreationPosition, IOnSurfaceComponent, - IRotatableComponent, IConvertGameObjectToEntity, ISerializationCallbackReceiver + IRotatableComponent, ISerializationCallbackReceiver { #region Data @@ -166,50 +167,6 @@ public float2 RotatedPosition { #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - // collision - var colliderComponent = gameObject.GetComponent(); - if (colliderComponent) { - dstManager.AddComponentData(entity, new KickerStaticData { - Center = Position, - FallIn = colliderComponent.FallIn, - FallThrough = colliderComponent.FallThrough, - HitAccuracy = colliderComponent.HitAccuracy, - Scatter = colliderComponent.Scatter, - LegacyMode = true, // todo colliderComponent.LegacyMode, - ZLow = Surface?.Height(Position) ?? PlayfieldHeight - }); - - dstManager.AddComponentData(entity, new KickerCollisionData { - BallEntity = Entity.Null, - LastCapturedBallEntity = Entity.Null - }); - - // if (!Data.LegacyMode) { - // // todo currently we don't allow non-legacy mode - // using (var blobBuilder = new BlobBuilder(Allocator.Temp)) { - // ref var blobAsset = ref blobBuilder.ConstructRoot(); - // var vertices = blobBuilder.Allocate(ref blobAsset.Vertices, Item.KickerHit.HitMesh.Length); - // var normals = blobBuilder.Allocate(ref blobAsset.Normals, Item.KickerHit.HitMesh.Length); - // for (var i = 0; i < Item.KickerHit.HitMesh.Length; i++) { - // var v = Item.KickerHit.HitMesh[i]; - // vertices[i] = new KickerMeshVertex { Vertex = v.ToUnityFloat3() }; - // normals[i] = new KickerMeshVertex { Vertex = new float3(KickerHitMesh.Vertices[i].Nx, KickerHitMesh.Vertices[i].Ny, KickerHitMesh.Vertices[i].Nz) }; - // } - // - // var blobAssetReference = blobBuilder.CreateBlobAssetReference(Allocator.Persistent); - // dstManager.AddComponentData(entity, new ColliderMeshData { Value = blobAssetReference }); - // } - // } - } - - // register - transform.GetComponentInParent().RegisterKicker(this, entity); - } - public override IEnumerable SetData(KickerData data) { var updatedComponents = new List { this }; @@ -223,7 +180,7 @@ public override IEnumerable SetData(KickerData data) #if UNITY_EDITOR var mf = GetComponent(); if (mf) { - MeshName = System.IO.Path.GetFileNameWithoutExtension(UnityEditor.AssetDatabase.GetAssetPath(mf.sharedMesh)); + MeshName = Path.GetFileNameWithoutExtension(AssetDatabase.GetAssetPath(mf.sharedMesh)); } #endif @@ -307,7 +264,7 @@ public void OnBeforeSerialize() #if UNITY_EDITOR // don't generate ids for prefabs, otherwise they'll show up in the instances. - if (UnityEditor.PrefabUtility.GetPrefabInstanceStatus(this) != UnityEditor.PrefabInstanceStatus.Connected) { + if (PrefabUtility.GetPrefabInstanceStatus(this) != PrefabInstanceStatus.Connected) { return; } var coilIds = new HashSet(); From 2a25c3c49c654fc6fe82e31768999150fb0fd085 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 6 Jan 2023 17:54:56 +0100 Subject: [PATCH 008/159] dots: Add bakers for metal wire guides. --- .../VPT/MetalWireGuide/MetalWireGuideBaker.cs | 31 +++++++++++++++++++ .../MetalWireGuideBaker.cs.meta | 3 ++ .../MetalWireGuide/MetalWireGuideComponent.cs | 12 +------ 3 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs new file mode 100644 index 000000000..2eabbfae8 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs @@ -0,0 +1,31 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.VPT.MetalWireGuide; + +namespace VisualPinball.Unity +{ + public class MetalWireGuideBaker : ItemBaker + { + public override void Bake(MetalWireGuideComponent authoring) + { + base.Bake(authoring); + + // register + GetComponentInParent().RegisterMetalWireGuide(authoring, GetEntity()); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs.meta new file mode 100644 index 000000000..3fd756b08 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c9015c8886cf41dab8a6dbc6d9603430 +timeCreated: 1673023719 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs index 040aeb698..8af72c31f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs @@ -24,8 +24,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Unity.Entities; -using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Math; using VisualPinball.Engine.VPT; @@ -36,7 +34,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Metal Wire Guide")] public class MetalWireGuideComponent : MainRenderableComponent, - IMetalWireGuideData, IConvertGameObjectToEntity + IMetalWireGuideData { #region Data @@ -98,14 +96,6 @@ public class MetalWireGuideComponent : MainRenderableComponent().RegisterMetalWireGuide(this, entity); - } - public override IEnumerable SetData(MetalWireGuideData data) { var updatedComponents = new List { this }; From 8e2b3df2a70b273f66dfb433cc6539fbb9f5fca3 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 6 Jan 2023 17:59:30 +0100 Subject: [PATCH 009/159] dots: Add plunger baker. --- .../VPT/Plunger/PlungerBaker.cs | 106 ++++++++++++++++++ .../VPT/Plunger/PlungerBaker.cs.meta | 3 + .../VPT/Plunger/PlungerComponent.cs | 83 +------------- 3 files changed, 110 insertions(+), 82 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs new file mode 100644 index 000000000..0a121a1e8 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs @@ -0,0 +1,106 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Mathematics; +using VisualPinball.Engine.VPT; +using VisualPinball.Engine.VPT.Plunger; + +namespace VisualPinball.Unity +{ + public class PlungerBaker : ItemBaker + { + public override void Bake(PlungerComponent authoring) + { + base.Bake(authoring); + + var collComponent = GetComponent(); + if (!collComponent) { + // without collider, the plunger is only a dead mesh. + return; + } + + var zHeight = authoring.PositionZ; + var x = authoring.Position.x - authoring.Width; + var y = authoring.Position.y + authoring.Height; + var x2 = authoring.Position.x + authoring.Width; + + var frameTop = authoring.Position.y - collComponent.Stroke; + var frameBottom = authoring.Position.y; + var frameLen = frameBottom - frameTop; + var restPos = collComponent.ParkPosition; + var position = frameTop + restPos * frameLen; + + var info = new ColliderInfo { + Entity = GetEntity(), + FireEvents = true, + IsEnabled = true, + ItemType = ItemType.Plunger, + }; + + AddComponent(new PlungerStaticData { + MomentumXfer = collComponent.MomentumXfer, + ScatterVelocity = collComponent.ScatterVelocity, + FrameStart = frameBottom, + FrameEnd = frameTop, + FrameLen = frameLen, + RestPosition = restPos, + IsAutoPlunger = collComponent.IsAutoPlunger, + IsMechPlunger = collComponent.IsMechPlunger, + SpeedFire = collComponent.SpeedFire, + NumFrames = (int)(collComponent.Stroke * (float)(PlungerMeshGenerator.PlungerFrameCount / 80.0f)) + 1, // 25 frames per 80 units travel + }); + + AddComponent(new PlungerColliderData { + LineSegSide0 = new LineCollider(new float2(x + 0.0001f, position), new float2(x, y), zHeight, zHeight + Plunger.PlungerHeight, info), + LineSegSide1 = new LineCollider(new float2(x2, y), new float2(x2 + 0.0001f, position), zHeight, zHeight + Plunger.PlungerHeight, info), + LineSegEnd = new LineCollider(new float2(x2, position), new float2(x, position), zHeight, zHeight + Plunger.PlungerHeight, info), + JointEnd0 = new LineZCollider(new float2(x, position), zHeight, zHeight + Plunger.PlungerHeight, info), + JointEnd1 = new LineZCollider(new float2(x2, position), zHeight, zHeight + Plunger.PlungerHeight, info), + }); + + AddComponent(new PlungerMovementData { + FireBounce = 0f, + Position = position, + RetractMotion = false, + ReverseImpulse = 0f, + Speed = 0f, + TravelLimit = frameTop, + FireSpeed = 0f, + FireTimer = 0 + }); + + AddComponent(new PlungerVelocityData { + Mech0 = 0f, + Mech1 = 0f, + Mech2 = 0f, + PullForce = 0f, + InitialSpeed = 0f, + AutoFireTimer = 0, + AddRetractMotion = false, + RetractWaitLoop = 0, + MechStrength = collComponent.MechStrength + }); + + AddComponent(new PlungerAnimationData { + Position = collComponent.ParkPosition + }); + + // register at player + GetComponentInParent().RegisterPlunger(authoring, GetEntity(), authoring.analogPlungerAction); + + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs.meta new file mode 100644 index 000000000..2f3e32026 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7ea09ece3265463c9ecdddb1b4e42893 +timeCreated: 1673024165 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs index fb81a5baf..6f25815a5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs @@ -33,7 +33,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Plunger")] public class PlungerComponent : MainRenderableComponent, - ICoilDeviceComponent, IOnSurfaceComponent, IConvertGameObjectToEntity + ICoilDeviceComponent, IOnSurfaceComponent { #region Data @@ -108,87 +108,6 @@ public override void UpdateTransforms() #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - var go = gameObject; - - var collComponent = GetComponent(); - if (!collComponent) { - // without collider, the plunger is only a dead mesh. - return; - } - - var zHeight = PositionZ; - var x = Position.x - Width; - var y = Position.y + Height; - var x2 = Position.x + Width; - - var frameTop = Position.y - collComponent.Stroke; - var frameBottom = Position.y; - var frameLen = frameBottom - frameTop; - var restPos = collComponent.ParkPosition; - var position = frameTop + restPos * frameLen; - - var info = new ColliderInfo { - Entity = entity, - FireEvents = true, - IsEnabled = true, - ItemType = ItemType.Plunger, - }; - - dstManager.AddComponentData(entity, new PlungerStaticData { - MomentumXfer = collComponent.MomentumXfer, - ScatterVelocity = collComponent.ScatterVelocity, - FrameStart = frameBottom, - FrameEnd = frameTop, - FrameLen = frameLen, - RestPosition = restPos, - IsAutoPlunger = collComponent.IsAutoPlunger, - IsMechPlunger = collComponent.IsMechPlunger, - SpeedFire = collComponent.SpeedFire, - NumFrames = (int)(collComponent.Stroke * (float)(PlungerMeshGenerator.PlungerFrameCount / 80.0f)) + 1, // 25 frames per 80 units travel - }); - - dstManager.AddComponentData(entity, new PlungerColliderData { - LineSegSide0 = new LineCollider(new float2(x + 0.0001f, position), new float2(x, y), zHeight, zHeight + Plunger.PlungerHeight, info), - LineSegSide1 = new LineCollider(new float2(x2, y), new float2(x2 + 0.0001f, position), zHeight, zHeight + Plunger.PlungerHeight, info), - LineSegEnd = new LineCollider(new float2(x2, position), new float2(x, position), zHeight, zHeight + Plunger.PlungerHeight, info), - JointEnd0 = new LineZCollider(new float2(x, position), zHeight, zHeight + Plunger.PlungerHeight, info), - JointEnd1 = new LineZCollider(new float2(x2, position), zHeight, zHeight + Plunger.PlungerHeight, info), - }); - - dstManager.AddComponentData(entity, new PlungerMovementData { - FireBounce = 0f, - Position = position, - RetractMotion = false, - ReverseImpulse = 0f, - Speed = 0f, - TravelLimit = frameTop, - FireSpeed = 0f, - FireTimer = 0 - }); - - dstManager.AddComponentData(entity, new PlungerVelocityData { - Mech0 = 0f, - Mech1 = 0f, - Mech2 = 0f, - PullForce = 0f, - InitialSpeed = 0f, - AutoFireTimer = 0, - AddRetractMotion = false, - RetractWaitLoop = 0, - MechStrength = collComponent.MechStrength - }); - - dstManager.AddComponentData(entity, new PlungerAnimationData { - Position = collComponent.ParkPosition - }); - - // register at player - GetComponentInParent().RegisterPlunger(this, entity, analogPlungerAction); - } - public override IEnumerable SetData(PlungerData data) { var updatedComponents = new List { this }; From 3f96a9a608233393f76149b776ebef1cc5626898 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 7 Jan 2023 13:08:04 +0100 Subject: [PATCH 010/159] dots: Add bakers for primitives and ramps. --- .../VPT/Primitive/PrimitiveBaker.cs | 31 +++++++++++++++++++ .../VPT/Primitive/PrimitiveBaker.cs.meta | 3 ++ .../VPT/Primitive/PrimitiveComponent.cs | 12 +------ .../VisualPinball.Unity/VPT/Ramp/RampBaker.cs | 30 ++++++++++++++++++ .../VPT/Ramp/RampBaker.cs.meta | 3 ++ .../VPT/Ramp/RampComponent.cs | 14 ++------- 6 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs new file mode 100644 index 000000000..846fd42c9 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs @@ -0,0 +1,31 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.VPT.Primitive; + +namespace VisualPinball.Unity +{ + public class PrimitiveBaker : ItemBaker + { + public override void Bake(PrimitiveComponent authoring) + { + base.Bake(authoring); + + // register + GetComponentInParent().RegisterPrimitive(authoring, GetEntity()); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs.meta new file mode 100644 index 000000000..5ece714f5 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5ce35e9d5b3c496090d2fc3d5fe22aac +timeCreated: 1673093011 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs index 71c6c4739..cf3ae5c28 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs @@ -23,7 +23,6 @@ using System; using System.Collections.Generic; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Math; @@ -37,7 +36,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Primitive")] public class PrimitiveComponent : MainRenderableComponent, IMeshGenerator, - IRotatableComponent, IConvertGameObjectToEntity + IRotatableComponent { #region Data @@ -100,15 +99,6 @@ public float2 RotatedPosition { #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - // register - transform.GetComponentInParent().RegisterPrimitive(this, entity); - } - - public override IEnumerable SetData(PrimitiveData data) { var updatedComponents = new List { this }; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs new file mode 100644 index 000000000..dd82f8290 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.VPT.Ramp; + +namespace VisualPinball.Unity +{ + public class RampBaker : ItemBaker + { + public override void Bake(RampComponent authoring) + { + base.Bake(authoring); + + GetComponentInParent().RegisterRamp(authoring, GetEntity()); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs.meta new file mode 100644 index 000000000..3142c0c3d --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: bec725d2d4fd43f78b960e620ca4a5dc +timeCreated: 1673093175 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs index 0b6969653..493d36133 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs @@ -25,19 +25,19 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.Math; using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.Ramp; using VisualPinball.Engine.VPT.Table; using MathF = VisualPinball.Engine.Math.MathF; +using Mesh = VisualPinball.Engine.VPT.Mesh; namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Ramp")] public class RampComponent : MainRenderableComponent, - IRampData, ISurfaceComponent, IConvertGameObjectToEntity + IRampData, ISurfaceComponent { #region Data @@ -126,7 +126,7 @@ public class RampComponent : MainRenderableComponent, public float Height(Vector2 pos) { var vVertex = new RampMeshGenerator(this).GetCentralCurve(); - Engine.VPT.Mesh.ClosestPointOnPolygon(vVertex, new Vertex2D(pos.x, pos.y), false, out var vOut, out var iSeg); + Mesh.ClosestPointOnPolygon(vVertex, new Vertex2D(pos.x, pos.y), false, out var vOut, out var iSeg); if (iSeg == -1) { return 0.0f; // Object is not on ramp path @@ -190,14 +190,6 @@ public override void UpdateVisibility() #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - // register - transform.GetComponentInParent().RegisterRamp(this, entity); - } - public override IEnumerable SetData(RampData data) { var updatedComponents = new List { this }; From c6f3c0075159474a279d9c5010272963fca378ea Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 7 Jan 2023 13:12:46 +0100 Subject: [PATCH 011/159] dots: Add rubber baker. --- .../VPT/Rubber/RubberBaker.cs | 31 +++++++++++++++++++ .../VPT/Rubber/RubberBaker.cs.meta | 3 ++ .../VPT/Rubber/RubberComponent.cs | 11 +------ 3 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs new file mode 100644 index 000000000..7accdc5ae --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs @@ -0,0 +1,31 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.VPT.Rubber; + +namespace VisualPinball.Unity +{ + public class RubberBaker : ItemBaker + { + public override void Bake(RubberComponent authoring) + { + base.Bake(authoring); + + // register + GetComponentInParent().RegisterRubber(authoring, GetEntity()); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs.meta new file mode 100644 index 000000000..1aee0db8b --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f5648372dbe2451e83fb775213540e72 +timeCreated: 1673093311 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs index 4a0698957..a2804c0e5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs @@ -24,7 +24,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.Math; using VisualPinball.Engine.VPT; @@ -35,7 +34,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Rubber")] public class RubberComponent : MainRenderableComponent, - IRubberData, IConvertGameObjectToEntity + IRubberData { #region Data @@ -93,14 +92,6 @@ public class RubberComponent : MainRenderableComponent, #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - // register - transform.GetComponentInParent().RegisterRubber(this, entity); - } - public override IEnumerable SetData(RubberData data) { var updatedComponents = new List { this }; From 37a8136db20f1c75a3129637800863032b31b711 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 7 Jan 2023 16:25:32 +0100 Subject: [PATCH 012/159] dots: Add bakers for spinner and surface. --- .../VPT/Spinner/SpinnerBaker.cs | 55 +++++++++++++++++++ .../VPT/Spinner/SpinnerBaker.cs.meta | 3 + .../VPT/Spinner/SpinnerComponent.cs | 31 +---------- .../VPT/Surface/SurfaceBaker.cs | 39 +++++++++++++ .../VPT/Surface/SurfaceBaker.cs.meta | 3 + .../VPT/Surface/SurfaceComponent.cs | 19 +------ 6 files changed, 102 insertions(+), 48 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs new file mode 100644 index 000000000..3830a63a7 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs @@ -0,0 +1,55 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Mathematics; +using VisualPinball.Engine.Common; +using VisualPinball.Engine.VPT.Spinner; + +namespace VisualPinball.Unity +{ + public class SpinnerBaker : ItemBaker + { + public override void Bake(SpinnerComponent authoring) + { + base.Bake(authoring); + + // physics collision data + var collComponent = GetComponent(); + if (collComponent) { + + AddComponent(new SpinnerStaticData { + AngleMax = math.radians(authoring.AngleMax), + AngleMin = math.radians(authoring.AngleMin), + Damping = math.pow(authoring.Damping, (float)PhysicsConstants.PhysFactor), + Elasticity = collComponent.Elasticity, + Height = authoring.Height + }); + } + + // animation + if (GetComponentInChildren()) { + AddComponent(new SpinnerMovementData { + Angle = math.radians(math.clamp(0.0f, authoring.AngleMin, authoring.AngleMax)), + AngleSpeed = 0f + }); + } + + // register + GetComponentInParent().RegisterSpinner(authoring, GetEntity()); + + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs.meta new file mode 100644 index 000000000..62eca60a0 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 860488c7d3274f9a82879a98ed9fd679 +timeCreated: 1673104612 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs index aa6a89339..6821b0683 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs @@ -36,7 +36,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Spinner")] public class SpinnerComponent : MainRenderableComponent, - ISwitchDeviceComponent, IOnSurfaceComponent, IConvertGameObjectToEntity + ISwitchDeviceComponent, IOnSurfaceComponent { #region Data @@ -129,35 +129,6 @@ public override void UpdateTransforms() #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - // physics collision data - var collComponent = GetComponent(); - if (collComponent) { - - dstManager.AddComponentData(entity, new SpinnerStaticData { - AngleMax = math.radians(AngleMax), - AngleMin = math.radians(AngleMin), - Damping = math.pow(Damping, (float)PhysicsConstants.PhysFactor), - Elasticity = collComponent.Elasticity, - Height = Height - }); - } - - // animation - if (GetComponentInChildren()) { - dstManager.AddComponentData(entity, new SpinnerMovementData { - Angle = math.radians(math.clamp(0.0f, AngleMin, AngleMax)), - AngleSpeed = 0f - }); - } - - // register - transform.GetComponentInParent().RegisterSpinner(this, entity); - } - public override IEnumerable SetData(SpinnerData data) { var updatedComponents = new List { this }; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs new file mode 100644 index 000000000..0e7cbf8ad --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs @@ -0,0 +1,39 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.VPT.Surface; + +namespace VisualPinball.Unity +{ + public class SurfaceBaker : ItemBaker + { + public override void Bake(SurfaceComponent authoring) + { + base.Bake(authoring); + + // physics collision data + var collComponent = GetComponentInChildren(); + if (collComponent) { + AddComponent(new LineSlingshotData { + IsDisabled = false, + Threshold = collComponent.SlingshotThreshold, + }); + } + + GetComponentInParent().RegisterSurface(authoring, GetEntity()); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs.meta new file mode 100644 index 000000000..461ba4b2f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ae5c95fc5fad42a693994927811e8acf +timeCreated: 1673104974 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs index 7b56dbeea..c68daf23a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs @@ -34,8 +34,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Surface")] - public class SurfaceComponent : MainRenderableComponent, - IConvertGameObjectToEntity, ISurfaceComponent + public class SurfaceComponent : MainRenderableComponent, ISurfaceComponent { #region Data @@ -76,22 +75,6 @@ public class SurfaceComponent : MainRenderableComponent, #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - // physics collision data - var collComponent = GetComponentInChildren(); - if (collComponent) { - dstManager.AddComponentData(entity, new LineSlingshotData { - IsDisabled = false, - Threshold = collComponent.SlingshotThreshold, - }); - } - - transform.GetComponentInParent().RegisterSurface(this, entity); - } - public override IEnumerable SetData(SurfaceData data) { var updatedComponents = new List { this }; From 2f7ea690a4d3a250d3533027f8fadabe3ac505a6 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 7 Jan 2023 16:31:14 +0100 Subject: [PATCH 013/159] dots: Add baker for trigger. --- .../VPT/Spinner/SpinnerComponent.cs | 3 -- .../VPT/Surface/SurfaceComponent.cs | 1 - .../VPT/Trigger/TriggerBaker.cs | 45 +++++++++++++++++++ .../VPT/Trigger/TriggerBaker.cs.meta | 3 ++ .../VPT/Trigger/TriggerComponent.cs | 26 +---------- 5 files changed, 49 insertions(+), 29 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs index 6821b0683..aa868e31a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs @@ -23,10 +23,7 @@ using System; using System.Collections.Generic; -using Unity.Entities; -using Unity.Mathematics; using UnityEngine; -using VisualPinball.Engine.Common; using VisualPinball.Engine.Game.Engines; using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.Spinner; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs index c68daf23a..d2db0bb58 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs @@ -24,7 +24,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.Math; using VisualPinball.Engine.VPT; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs new file mode 100644 index 000000000..124866ec7 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs @@ -0,0 +1,45 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.VPT.Trigger; + +namespace VisualPinball.Unity +{ + public class TriggerBaker : ItemBaker + { + public override void Bake(TriggerComponent authoring) + { + base.Bake(authoring); + + var collComponent = GetComponentInChildren(); + var animComponent = GetComponentInChildren(); + var meshComponent = GetComponentInChildren(); + if (collComponent && animComponent && meshComponent) { + AddComponent(new TriggerAnimationData()); + AddComponent(new TriggerMovementData()); + AddComponent(new TriggerStaticData { + AnimSpeed = animComponent.AnimSpeed, + Radius = collComponent.HitCircleRadius, + Shape = meshComponent.Shape, + TableScaleZ = 1f + }); + } + + // register + GetComponentInParent().RegisterTrigger(authoring, GetEntity()); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs.meta new file mode 100644 index 000000000..848c4a174 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6c66eb4fd3594e32bf152aa3fbd6d3f6 +timeCreated: 1673105180 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs index b5823ab99..5a32a3318 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs @@ -24,9 +24,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Unity.Entities; using Unity.Mathematics; -using UnityEditor; using UnityEngine; using VisualPinball.Engine.Game.Engines; using VisualPinball.Engine.Math; @@ -38,7 +36,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Game Item/Trigger")] public class TriggerComponent : MainRenderableComponent, - ITriggerComponent, IOnSurfaceComponent, IConvertGameObjectToEntity + ITriggerComponent, IOnSurfaceComponent { #region Data @@ -119,28 +117,6 @@ public override void UpdateTransforms() #region Conversion - public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) - { - Convert(entity, dstManager); - - var collComponent = GetComponentInChildren(); - var animComponent = GetComponentInChildren(); - var meshComponent = GetComponentInChildren(); - if (collComponent && animComponent && meshComponent) { - dstManager.AddComponentData(entity, new TriggerAnimationData()); - dstManager.AddComponentData(entity, new TriggerMovementData()); - dstManager.AddComponentData(entity, new TriggerStaticData { - AnimSpeed = animComponent.AnimSpeed, - Radius = collComponent.HitCircleRadius, - Shape = meshComponent.Shape, - TableScaleZ = 1f - }); - } - - // register - transform.GetComponentInParent().RegisterTrigger(this, entity); - } - public override IEnumerable SetData(TriggerData data) { var updatedComponents = new List { this }; From 0131aa76d0e6534b6d4c35660582371e2fceb746 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 7 Jan 2023 16:50:37 +0100 Subject: [PATCH 014/159] dots: Fix item systems. --- .../VisualPinball.Unity/Game/Player.cs | 2 +- .../VisualPinball.Unity/Game/SwitchHandler.cs | 2 +- .../Game/VisualPinballSimulationSystemGroup.cs | 12 ++++++------ .../VisualPinball.Unity/Game/WirePlayer.cs | 2 +- .../Physics/Collision/ContactSystem.cs | 2 +- .../Physics/Collision/DynamicCollisionSystem.cs | 2 +- .../Physics/Collision/DynamicNarrowPhaseSystem.cs | 2 +- .../Physics/Collision/StaticBroadPhaseSystem.cs | 2 +- .../Physics/Collision/StaticCollisionSystem.cs | 4 ++-- .../Physics/Collision/StaticNarrowPhaseSystem.cs | 2 +- .../Physics/Engine/DefaultPhysicsEngine.cs | 4 ++-- .../VPT/Ball/BallDisplacementSystem.cs | 2 +- .../VisualPinball.Unity/VPT/Ball/BallManager.cs | 4 ++-- .../VPT/Ball/BallRingCounterSystem.cs | 2 +- .../VPT/Ball/BallSpinHackSystem.cs | 2 +- .../VPT/Bumper/BumperRingAnimationSystem.cs | 2 +- .../VPT/Bumper/BumperSkirtAnimationSystem.cs | 2 +- .../VisualPinball.Unity/VPT/CollidableApi.cs | 2 +- .../VPT/Flipper/FlipperDisplacementSystem.cs | 4 ++-- .../VPT/Gate/GateDisplacementSystem.cs | 2 +- .../VPT/HitTarget/DropTargetAnimationSystem.cs | 2 +- .../VPT/HitTarget/DropTargetApi.cs | 2 +- .../VPT/HitTarget/HitTargetAnimationSystem.cs | 2 +- .../VisualPinball.Unity/VPT/ItemApi.cs | 2 +- .../VPT/Playfield/PlayfieldComponent.cs | 2 +- .../VPT/Plunger/PlungerDisplacementSystem.cs | 2 +- .../VPT/Spinner/SpinnerDisplacementSystem.cs | 2 +- .../VPT/Teleporter/TeleporterApi.cs | 2 +- .../VPT/Trigger/TriggerAnimationSystem.cs | 2 +- 29 files changed, 38 insertions(+), 38 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 47d088618..71553c0e8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -158,7 +158,7 @@ private void Awake() if (!string.IsNullOrEmpty(debugUiId)) { EngineProvider.Set(debugUiId); } - _simulationSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem(); + _simulationSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); } private void Start() diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs index 10808496c..90ee21b34 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs @@ -58,7 +58,7 @@ public class SwitchHandler private readonly Dictionary _switchStatuses = new Dictionary(); - private static VisualPinballSimulationSystemGroup SimulationSystemGroup => World.DefaultGameObjectInjectionWorld.GetOrCreateSystem(); + private static VisualPinballSimulationSystemGroup SimulationSystemGroup => World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); public SwitchHandler(string name, Player player, bool isEnabled = false) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs index ce713a370..cdc455239 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs @@ -61,12 +61,12 @@ protected override void OnCreate() _time.Start(); - _createBallEntityCommandBufferSystem = World.GetOrCreateSystem(); - _velocitiesSystemGroup = World.GetOrCreateSystem(); - _simulateCycleSystemGroup = World.GetOrCreateSystem(); - _ballRingCounterSystem = World.GetOrCreateSystem(); - _updateAnimationsSystemGroup = World.GetOrCreateSystem(); - _transformMeshesSystemGroup = World.GetOrCreateSystem(); + _createBallEntityCommandBufferSystem = World.GetOrCreateSystemManaged(); + _velocitiesSystemGroup = World.GetOrCreateSystemManaged(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); + _ballRingCounterSystem = World.GetOrCreateSystemManaged(); + _updateAnimationsSystemGroup = World.GetOrCreateSystemManaged(); + _transformMeshesSystemGroup = World.GetOrCreateSystemManaged(); _systemsToUpdate.Add(_createBallEntityCommandBufferSystem); _systemsToUpdate.Add(_velocitiesSystemGroup); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs index c34794d87..ad6537442 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs @@ -45,7 +45,7 @@ public class WirePlayer private InputManager _inputManager; private SwitchPlayer _switchPlayer; - private static VisualPinballSimulationSystemGroup SimulationSystemGroup => World.DefaultGameObjectInjectionWorld.GetOrCreateSystem(); + private static VisualPinballSimulationSystemGroup SimulationSystemGroup => World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); internal Dictionary WireStatuses { get; } = new Dictionary(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs index 7d417000f..9fec99695 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs @@ -35,7 +35,7 @@ internal class ContactSystem : SystemBase protected override void OnCreate() { - _simulateCycleSystemGroup = World.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); _collDataEntityQuery = EntityManager.CreateEntityQuery(typeof(ColliderData)); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs index 167f4a897..bd81fd49b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs @@ -27,7 +27,7 @@ internal class DynamicCollisionSystem : SystemBase protected override void OnCreate() { - _simulateCycleSystemGroup = World.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); } protected override void OnUpdate() diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs index aede3be70..53fb2ab47 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs @@ -27,7 +27,7 @@ internal class DynamicNarrowPhaseSystem : SystemBase protected override void OnCreate() { - _simulateCycleSystemGroup = World.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); } protected override void OnUpdate() diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs index fa47a9c36..918b78be9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs @@ -30,7 +30,7 @@ internal class StaticBroadPhaseSystem : SystemBase protected override void OnCreate() { _quadTreeEntityQuery = EntityManager.CreateEntityQuery(typeof(QuadTreeData)); - _simulateCycleSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); } protected override void OnUpdate() diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs index a546130c9..9a143d7b8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs @@ -38,8 +38,8 @@ internal class StaticCollisionSystem : SystemBase protected override void OnCreate() { - _visualPinballSimulationSystemGroup = World.GetOrCreateSystem(); - _simulateCycleSystemGroup = World.GetOrCreateSystem(); + _visualPinballSimulationSystemGroup = World.GetOrCreateSystemManaged(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); _collDataEntityQuery = EntityManager.CreateEntityQuery(typeof(ColliderData)); _eventQueue = new NativeQueue(Allocator.Persistent); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs index 8c4cb5068..0217e5eed 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs @@ -32,7 +32,7 @@ internal class StaticNarrowPhaseSystem : SystemBase protected override void OnCreate() { - _simulateCycleSystemGroup = World.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); _collDataEntityQuery = EntityManager.CreateEntityQuery(typeof(ColliderData)); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs index 7b9cf1554..a15ef6fc2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs @@ -53,8 +53,8 @@ public void Init(TableComponent tableComponent, BallManager ballManager) _ballDataQuery = _entityManager.CreateEntityQuery(ComponentType.ReadOnly()); - _visualPinballSimulationSystemGroup = _entityManager.World.GetOrCreateSystem(); - var simulateCycleSystemGroup = _entityManager.World.GetOrCreateSystem(); + _visualPinballSimulationSystemGroup = _entityManager.World.GetOrCreateSystemManaged(); + var simulateCycleSystemGroup = _entityManager.World.GetOrCreateSystemManaged(); _visualPinballSimulationSystemGroup.Enabled = true; simulateCycleSystemGroup.PhysicsEngine = this; // needed for flipper status update we don't do in all engines diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs index 6eb140d6c..ed1a055f8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs @@ -30,7 +30,7 @@ internal class BallDisplacementSystem : SystemBase protected override void OnCreate() { - _simulateCycleSystemGroup = World.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); } protected override void OnUpdate() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index 700cb6146..630653a79 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -99,7 +99,7 @@ public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float _player.Balls[entity] = ballGo; var world = World.DefaultGameObjectInjectionWorld; - var ecbs = world.GetOrCreateSystem(); + var ecbs = world.GetOrCreateSystemManaged(); var ecb = ecbs.CreateCommandBuffer(); ecb.AddBuffer(entity); @@ -163,7 +163,7 @@ public void DestroyEntity(Entity ballEntity) // destroy entity World.DefaultGameObjectInjectionWorld - .GetOrCreateSystem() + .GetOrCreateSystemManaged() .CreateCommandBuffer() .DestroyEntity(ballEntity); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs index 755a9b6aa..c5190d81a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs @@ -26,7 +26,7 @@ internal class BallRingCounterSystem : SystemBase protected override void OnUpdate() { - var lastPositionBuffer = GetBufferFromEntity(); + var lastPositionBuffer = GetBufferLookup(); Entities .WithNativeDisableParallelForRestriction(lastPositionBuffer) .ForEach((Entity entity, ref BallData ball) => diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs index 96b8ab4a1..06a7a515c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs @@ -25,7 +25,7 @@ internal class BallSpinHackSystem : SystemBase { protected override void OnUpdate() { - var lastPositionBuffer = GetBufferFromEntity(true); + var lastPositionBuffer = GetBufferLookup(true); Entities .WithReadOnly(lastPositionBuffer) .ForEach((Entity entity, ref BallData ball, in CollisionEventData collEvent) => diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs index 80bc689b5..66e918240 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs @@ -26,7 +26,7 @@ internal class BumperRingAnimationSystem : SystemBase protected override void OnUpdate() { - var dTime = Time.DeltaTime * 1000; + var dTime = SystemAPI.Time.DeltaTime * 1000; var marker = PerfMarker; Entities diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs index bd0bbad1c..e8230ac00 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs @@ -27,7 +27,7 @@ internal class BumperSkirtAnimationSystem : SystemBase protected override void OnUpdate() { - var dTime = Time.DeltaTime * 1000; + var dTime = SystemAPI.Time.DeltaTime * 1000; var marker = PerfMarker; Entities diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs index e752663ab..df61e5766 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs @@ -45,7 +45,7 @@ public bool IsCollidable { protected CollidableApi(GameObject go, Entity entity, Player player) : base(go, player) { if (World.DefaultGameObjectInjectionWorld != null) { - _simulateCycleSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); } EntityManager = World.DefaultGameObjectInjectionWorld != null ? World.DefaultGameObjectInjectionWorld.EntityManager : default; Entity = entity; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs index 5d0e33d4d..09032e644 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs @@ -36,7 +36,7 @@ internal class FlipperDisplacementSystem : SystemBase protected override void OnCreate() { _player = Object.FindObjectOfType(); - _simulateCycleSystemGroup = World.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); _eventQueue = new NativeQueue(Allocator.Persistent); } @@ -50,7 +50,7 @@ protected override void OnUpdate() var dTime = _simulateCycleSystemGroup.HitTime; var events = _eventQueue.AsParallelWriter(); var marker = PerfMarker; - var currentTime = Time.ElapsedTime; + var currentTime = SystemAPI.Time.ElapsedTime; Entities.WithName("FlipperDisplacementJob").ForEach((Entity entity, ref FlipperMovementData state, ref FlipperTricksData tricks, in FlipperStaticData data) => { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs index d82478f53..440873cb4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs @@ -35,7 +35,7 @@ internal class GateDisplacementSystem : SystemBase protected override void OnCreate() { _player = Object.FindObjectOfType(); - _simulateCycleSystemGroup = World.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); _eventQueue = new NativeQueue(Allocator.Persistent); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs index f05ae26a5..e68fbe36a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs @@ -34,7 +34,7 @@ internal class DropTargetAnimationSystem : SystemBase protected override void OnCreate() { _player = Object.FindObjectOfType(); - _visualPinballSimulationSystemGroup = World.GetOrCreateSystem(); + _visualPinballSimulationSystemGroup = World.GetOrCreateSystemManaged(); _eventQueue = new NativeQueue(Allocator.Persistent); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs index 959d5566d..5403695dd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs @@ -81,7 +81,7 @@ private void SetIsDropped(bool isDropped) } else { data.MoveDown = false; - data.TimeStamp = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem().TimeMsec; + data.TimeStamp = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged().TimeMsec; } } else { data.IsDropped = isDropped; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs index 63191eba2..8fd53b3db 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs @@ -30,7 +30,7 @@ internal class HitTargetAnimationSystem : SystemBase protected override void OnCreate() { - _visualPinballSimulationSystemGroup = World.GetOrCreateSystem(); + _visualPinballSimulationSystemGroup = World.GetOrCreateSystemManaged(); _eventQueue = new NativeQueue(Allocator.Persistent); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs index 5360f176a..91d2a1c98 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs @@ -41,7 +41,7 @@ public abstract class ItemApi private protected TableApi TableApi => Player.TableApi; - internal VisualPinballSimulationSystemGroup SimulationSystemGroup => World.DefaultGameObjectInjectionWorld.GetOrCreateSystem(); + internal VisualPinballSimulationSystemGroup SimulationSystemGroup => World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); private protected readonly Player Player; private protected readonly SwitchHandler SwitchHandler; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs index 12a7e139a..5e29539df 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs @@ -107,7 +107,7 @@ private void Awake() GetComponentInParent().RegisterPlayfield(gameObject); var meshComp = GetComponentInChildren(); if (meshComp) { - World.DefaultGameObjectInjectionWorld.GetOrCreateSystem().CollideAgainstPlayfieldPlane = meshComp.AutoGenerate; + World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged().CollideAgainstPlayfieldPlane = meshComp.AutoGenerate; } transform.RotateAround(Vector3.zero, Vector3.right, -RenderSlope); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs index ab6b15616..6b92b4210 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs @@ -34,7 +34,7 @@ internal class PlungerDisplacementSystem : SystemBase protected override void OnCreate() { _player = Object.FindObjectOfType(); - _simulateCycleSystemGroup = World.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); _eventQueue = new NativeQueue(Allocator.Persistent); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs index a60e16ed8..8e6d91243 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs @@ -36,7 +36,7 @@ internal class SpinnerDisplacementSystem : SystemBase protected override void OnCreate() { _player = Object.FindObjectOfType(); - _simulateCycleSystemGroup = World.GetOrCreateSystem(); + _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); _eventQueue = new NativeQueue(Allocator.Persistent); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs index d39cf223c..3f71d0605 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs @@ -43,7 +43,7 @@ internal TeleporterApi(GameObject go, Player player) { _component = go.GetComponentInChildren(); _player = player; - _simulationSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem(); + _simulationSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); } void IApi.OnInit(BallManager ballManager) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs index 4ba2d2fa5..1a2fc2f76 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs @@ -27,7 +27,7 @@ internal class TriggerAnimationSystem : SystemBase protected override void OnUpdate() { - var dTime = Time.DeltaTime * 1000; + var dTime = SystemAPI.Time.DeltaTime * 1000; var marker = PerfMarker; Entities From b0e31260b478353eb4ba45c594993c70dc2ad536 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 7 Jan 2023 17:05:45 +0100 Subject: [PATCH 015/159] dots: IDE is green now. --- .../VPT/Primitive/PrimitiveInspector.cs | 8 ++++---- .../Game/VisualPinballSimulationSystemGroup.cs | 8 ++++---- .../Physics/Collision/ContactSystem.cs | 4 ++-- .../Physics/Collision/DynamicBroadPhaseSystem.cs | 4 ++-- .../Physics/Collision/DynamicCollisionSystem.cs | 6 +++--- .../Physics/Collision/DynamicNarrowPhaseSystem.cs | 4 ++-- .../Physics/Collision/StaticBroadPhaseSystem.cs | 2 +- .../Physics/Collision/StaticCollisionSystem.cs | 2 +- .../Physics/Collision/StaticNarrowPhaseSystem.cs | 2 +- .../Physics/SystemGroup/SimulateBuildSystem.cs | 2 +- .../Physics/SystemGroup/SimulateCycleSystemGroup.cs | 2 +- .../Physics/SystemGroup/TransformMeshesSystemGroup.cs | 2 +- .../Physics/SystemGroup/UpdateAnimationsSystemGroup.cs | 2 +- .../Physics/SystemGroup/UpdateDisplacementSystemGroup.cs | 2 +- .../Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs | 2 +- .../VPT/Ball/BallDisplacementSystem.cs | 2 +- .../VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs | 2 +- .../VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs | 2 +- .../VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs | 2 +- .../VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs | 2 +- .../VPT/Bumper/BumperRingAnimationSystem.cs | 2 +- .../VPT/Bumper/BumperRingMovementSystem.cs | 2 +- .../VPT/Bumper/BumperSkirtAnimationSystem.cs | 2 +- .../VPT/Bumper/BumperSkirtMovementSystem.cs | 2 +- .../VPT/Flipper/FlipperDisplacementSystem.cs | 2 +- .../VPT/Flipper/FlipperRotateSystem.cs | 2 +- .../VPT/Flipper/FlipperVelocitySystem.cs | 2 +- .../VPT/Gate/GateDisplacementSystem.cs | 2 +- .../VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs | 2 +- .../VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs | 2 +- .../VPT/HitTarget/DropTargetAnimationSystem.cs | 2 +- .../VPT/HitTarget/DropTargetTransformationSystem.cs | 2 +- .../VPT/HitTarget/HitTargetAnimationSystem.cs | 2 +- .../VPT/HitTarget/HitTargetTransformationSystem.cs | 2 +- .../VPT/Plunger/PlungerAnimationSystem.cs | 2 +- .../VPT/Plunger/PlungerDisplacementSystem.cs | 2 +- .../VPT/Plunger/PlungerTransformationSystem.cs | 2 +- .../VPT/Plunger/PlungerVelocitySystem.cs | 2 +- .../VPT/Spinner/SpinnerDisplacementSystem.cs | 2 +- .../VPT/Spinner/SpinnerMovementSystem.cs | 2 +- .../VPT/Spinner/SpinnerVelocitySystem.cs | 2 +- .../VPT/Trigger/TriggerAnimationSystem.cs | 2 +- .../VPT/Trigger/TriggerMovementSystem.cs | 2 +- 43 files changed, 54 insertions(+), 54 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/Primitive/PrimitiveInspector.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/Primitive/PrimitiveInspector.cs index baa2cb860..d552440b8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/Primitive/PrimitiveInspector.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/Primitive/PrimitiveInspector.cs @@ -90,8 +90,8 @@ public static void MakePrimitive() var cc = go.AddComponent(); cc.enabled = true; - var cte = go.AddComponent(); - cte.ConversionMode = ConvertToEntity.Mode.ConvertAndInjectGameObject; + // var cte = go.AddComponent(); + // cte.ConversionMode = ConvertToEntity.Mode.ConvertAndInjectGameObject; } } @@ -117,8 +117,8 @@ public static void MakeCollider() var cc = go.AddComponent(); cc.enabled = true; - var cte = go.AddComponent(); - cte.ConversionMode = ConvertToEntity.Mode.ConvertAndInjectGameObject; + // var cte = go.AddComponent(); + // cte.ConversionMode = ConvertToEntity.Mode.ConvertAndInjectGameObject; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs index cdc455239..22273b495 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs @@ -27,7 +27,7 @@ namespace VisualPinball.Unity /// Main physics simulation system, executed once per frame. /// [UpdateBefore(typeof(TransformSystemGroup))] - internal class VisualPinballSimulationSystemGroup : ComponentSystemGroup + internal partial class VisualPinballSimulationSystemGroup : ComponentSystemGroup { public double PhysicsDiffTime; public double CurrentPhysicsTime => _currentPhysicsTime * (1.0 / PhysicsConstants.DefaultStepTime); @@ -102,7 +102,7 @@ protected override void OnUpdate() while (_currentPhysicsFrameTime < initialTimeUsec) { - TimeMsec = (uint) (Time.ElapsedTime * 1000); + TimeMsec = (uint) (SystemAPI.Time.ElapsedTime * 1000); PhysicsDiffTime = (_nextPhysicsFrameTime - _currentPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime); // update velocities @@ -145,7 +145,7 @@ private ulong GetTargetTime() switch (Timing) { case TimingMode.Atleast60: - var dt = (ulong)(Time.DeltaTime * 1000000); + var dt = (ulong)(SystemAPI.Time.DeltaTime * 1000000); if (_currentPhysicsTime > 0 && dt > dt60fps) { dt = dt60fps; } @@ -155,7 +155,7 @@ private ulong GetTargetTime() return _currentPhysicsTime + dt60fps; case TimingMode.UnityTime: - return (ulong)(Time.ElapsedTime * 1000000); + return (ulong)(SystemAPI.Time.ElapsedTime * 1000000); case TimingMode.SystemTime: return (ulong) (_time.Elapsed.TotalMilliseconds * 1000); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs index 9fec99695..79cd74549 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs @@ -24,7 +24,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class ContactSystem : SystemBase + internal partial class ContactSystem : SystemBase { private SimulateCycleSystemGroup _simulateCycleSystemGroup; @@ -53,7 +53,7 @@ protected override void OnUpdate() var collEntity = _collDataEntityQuery.GetSingletonEntity(); var collData = EntityManager.GetComponentData(collEntity); var contacts = _simulateCycleSystemGroup.Contacts; - var ballsLookup = GetComponentDataFromEntity(); + var ballsLookup = GetComponentLookup(); var marker = PerfMarker; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs index 394ecdc65..45f6c8d55 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class DynamicBroadPhaseSystem : SystemBase + internal partial class DynamicBroadPhaseSystem : SystemBase { private EntityQuery _ballQuery; private static readonly ProfilerMarker PerfMarker1 = new ProfilerMarker("DynamicBroadPhaseSystem.CreateKdTree"); @@ -46,7 +46,7 @@ protected override void OnUpdate() PerfMarker1.End(); - var overlappingEntities = GetBufferFromEntity(); + var overlappingEntities = GetBufferLookup(); var marker = PerfMarker2; Entities diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs index bd81fd49b..39e2585fc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs @@ -20,7 +20,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class DynamicCollisionSystem : SystemBase + internal partial class DynamicCollisionSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("DynamicCollisionSystem"); private SimulateCycleSystemGroup _simulateCycleSystemGroup; @@ -35,8 +35,8 @@ protected override void OnUpdate() var marker = PerfMarker; var hitTime = _simulateCycleSystemGroup.HitTime; var swapBallCollisionHandling = _simulateCycleSystemGroup.SwapBallCollisionHandling; - var balls = GetComponentDataFromEntity(); - var collEvents = GetComponentDataFromEntity(true); + var balls = GetComponentLookup(); + var collEvents = GetComponentLookup(true); Entities .WithName("DynamicCollisionJob") diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs index 53fb2ab47..9d7d4b642 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs @@ -20,7 +20,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class DynamicNarrowPhaseSystem : SystemBase + internal partial class DynamicNarrowPhaseSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("DynamicNarrowPhaseSystem"); private SimulateCycleSystemGroup _simulateCycleSystemGroup; @@ -32,7 +32,7 @@ protected override void OnCreate() protected override void OnUpdate() { - var ballsLookup = GetComponentDataFromEntity(); + var ballsLookup = GetComponentLookup(); var contacts = _simulateCycleSystemGroup.Contacts; var marker = PerfMarker; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs index 918b78be9..66b134d8e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs @@ -20,7 +20,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class StaticBroadPhaseSystem : SystemBase + internal partial class StaticBroadPhaseSystem : SystemBase { private EntityQuery _quadTreeEntityQuery; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs index 9a143d7b8..4e1540be6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs @@ -27,7 +27,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class StaticCollisionSystem : SystemBase + internal partial class StaticCollisionSystem : SystemBase { private Player _player; private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs index 0217e5eed..8c84b5a78 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class StaticNarrowPhaseSystem : SystemBase + internal partial class StaticNarrowPhaseSystem : SystemBase { public bool CollideAgainstPlayfieldPlane; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs index a976fd341..a87ff22a1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity { [UpdateBefore(typeof(TransformMeshesSystemGroup))] - internal class SimulateBuildSystem : SystemBase + internal partial class SimulateBuildSystem : SystemBase { private float4x4 _baseTransform; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs index b76e92dda..a849db4b0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs @@ -27,7 +27,7 @@ namespace VisualPinball.Unity /// The main simulation loop /// [DisableAutoCreation] - internal class SimulateCycleSystemGroup : ComponentSystemGroup + internal partial class SimulateCycleSystemGroup : ComponentSystemGroup { /// /// Time of the next collision; other systems can update this. diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs index a59943903..e6e043895 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs @@ -18,7 +18,7 @@ namespace VisualPinball.Unity { - internal class TransformMeshesSystemGroup : ComponentSystemGroup + internal partial class TransformMeshesSystemGroup : ComponentSystemGroup { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs index e80649d50..7b7a40259 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs @@ -19,7 +19,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class UpdateAnimationsSystemGroup : ComponentSystemGroup + internal partial class UpdateAnimationsSystemGroup : ComponentSystemGroup { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs index 971fcf294..66dfc7f53 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs @@ -19,7 +19,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class UpdateDisplacementSystemGroup : ComponentSystemGroup + internal partial class UpdateDisplacementSystemGroup : ComponentSystemGroup { } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs index 41d7c672a..202d089f6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs @@ -19,7 +19,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class UpdateVelocitiesSystemGroup : ComponentSystemGroup + internal partial class UpdateVelocitiesSystemGroup : ComponentSystemGroup { } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs index ed1a055f8..2a9b91664 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal class BallDisplacementSystem : SystemBase + internal partial class BallDisplacementSystem : SystemBase { private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs index 6fe7d797c..923971e04 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal class BallMovementSystem : SystemBase + internal partial class BallMovementSystem : SystemBase { private float4x4 _baseTransform; private Player _player; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs index c5190d81a..5ea155dc3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs @@ -20,7 +20,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class BallRingCounterSystem : SystemBase + internal partial class BallRingCounterSystem : SystemBase { public const int MaxBallTrailPos = 10; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs index 06a7a515c..c507da3c7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { [DisableAutoCreation] - internal class BallSpinHackSystem : SystemBase + internal partial class BallSpinHackSystem : SystemBase { protected override void OnUpdate() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs index 6667ee1c9..fd137a32e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs @@ -25,7 +25,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal class BallVelocitySystem : SystemBase + internal partial class BallVelocitySystem : SystemBase { private float3 _gravity; private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallVelocitySystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs index 66e918240..f3fe1601f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs @@ -20,7 +20,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal class BumperRingAnimationSystem : SystemBase + internal partial class BumperRingAnimationSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperRingAnimationSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs index 5771ff2e2..10963f5fc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal class BumperRingMovementSystem : SystemBase + internal partial class BumperRingMovementSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperRingMovementSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs index e8230ac00..38ebbb21c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal class BumperSkirtAnimationSystem : SystemBase + internal partial class BumperSkirtAnimationSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperSkirtAnimationSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs index fead826ca..e18c71d4b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal class BumperSkirtMovementSystem : SystemBase + internal partial class BumperSkirtMovementSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperSkirtMovementSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs index 09032e644..ee2cfea96 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs @@ -25,7 +25,7 @@ namespace VisualPinball.Unity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal class FlipperDisplacementSystem : SystemBase + internal partial class FlipperDisplacementSystem : SystemBase { private Player _player; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs index 45d2de024..ef3d1b7c2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal class FlipperRotateSystem : SystemBase + internal partial class FlipperRotateSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("FlipperRotateSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs index e3f631c01..28fff190d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs @@ -25,7 +25,7 @@ namespace VisualPinball.Unity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal class FlipperVelocitySystem : SystemBase + internal partial class FlipperVelocitySystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("FlipperVelocitySystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs index 440873cb4..e84f286c3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs @@ -24,7 +24,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal class GateDisplacementSystem : SystemBase + internal partial class GateDisplacementSystem : SystemBase { private Player _player; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs index 19683d84e..bf97f4cd1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal class GateMovementSystem : SystemBase + internal partial class GateMovementSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("GateMovementSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs index c26d0a073..d484ab4ec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs @@ -24,7 +24,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal class GateVelocitySystem : SystemBase + internal partial class GateVelocitySystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("GateVelocitySystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs index e68fbe36a..0c3abd2ca 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal class DropTargetAnimationSystem : SystemBase + internal partial class DropTargetAnimationSystem : SystemBase { private Player _player; private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs index 31d4f1f9f..63e257b9c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal class DropTargetTransformationSystem : SystemBase + internal partial class DropTargetTransformationSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker(nameof(DropTargetTransformationSystem)); private Player _player; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs index 8fd53b3db..465206091 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal class HitTargetAnimationSystem : SystemBase + internal partial class HitTargetAnimationSystem : SystemBase { private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; private NativeQueue _eventQueue; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs index 6f2925a3f..ac4ca81bd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal class HitTargetTransformationSystem : SystemBase + internal partial class HitTargetTransformationSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker(nameof(HitTargetTransformationSystem)); private Player _player; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs index 0d2943df8..2e6f0db32 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal class PlungerAnimationSystem : SystemBase + internal partial class PlungerAnimationSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("PlungerAnimationSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs index 6b92b4210..9c4ae5e03 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs @@ -24,7 +24,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal class PlungerDisplacementSystem : SystemBase + internal partial class PlungerDisplacementSystem : SystemBase { private Player _player; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs index 9d84108f4..d62c837df 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal class PlungerTransformationSystem : SystemBase + internal partial class PlungerTransformationSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("PlungerTransformationSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs index 29994ca42..7e0c1d500 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs @@ -20,7 +20,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal class PlungerVelocitySystem : SystemBase + internal partial class PlungerVelocitySystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("PlungerVelocitySystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs index 8e6d91243..def3a3627 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs @@ -26,7 +26,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal class SpinnerDisplacementSystem : SystemBase + internal partial class SpinnerDisplacementSystem : SystemBase { private Player _player; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs index 5fa5f0ac3..487109924 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal class SpinnerMovementSystem : SystemBase + internal partial class SpinnerMovementSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("SpinnerMovementSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs index 4986b510d..9ff2c88f1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal class SpinnerVelocitySystem : SystemBase + internal partial class SpinnerVelocitySystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("SpinnerVelocitySystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs index 1a2fc2f76..844ee1db0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal class TriggerAnimationSystem : SystemBase + internal partial class TriggerAnimationSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("TriggerAnimationSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs index 2f5ce005d..5f176f1c7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs @@ -22,7 +22,7 @@ namespace VisualPinball.Unity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal class TriggerMovementSystem : SystemBase + internal partial class TriggerMovementSystem : SystemBase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("TriggerMovementSystem"); From 8f21f53a2f8131914aaf7d7d4a51fa1cad00e37b Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 8 Jan 2023 14:46:09 +0100 Subject: [PATCH 016/159] project: Fix entities version number. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 02d413fb2..d22a023ef 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "unity": "2021.3", "unityRelease": "0f1", "dependencies": { - "com.unity.entities": "1.0-pre.15", + "com.unity.entities": "1.0.0-pre.15", "com.unity.formats.fbx": "4.1.2", "com.unity.inputsystem": "1.3.0", "com.unity.ugui": "1.0.0", From e111f65f43b50f6082d1fabb0cf2316697a123b9 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 9 Jan 2023 00:52:32 +0100 Subject: [PATCH 017/159] dots: Rename VisualPinball.Unity to VisualPinballUnity for system classes. --- VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs | 1 + .../VisualPinball.Unity/Game/SwitchHandler.cs | 1 + .../Game/VisualPinballSimulationSystemGroup.cs | 2 +- .../VisualPinball.Unity/Game/WirePlayer.cs | 1 + .../Physics/Collision/ContactSystem.cs | 8 +++++--- .../Physics/Collision/DynamicBroadPhaseSystem.cs | 3 ++- .../Physics/Collision/DynamicCollisionSystem.cs | 3 ++- .../Physics/Collision/DynamicNarrowPhaseSystem.cs | 3 ++- .../Physics/Collision/StaticBroadPhaseSystem.cs | 3 ++- .../Physics/Collision/StaticCollisionSystem.cs | 3 ++- .../Physics/Collision/StaticNarrowPhaseSystem.cs | 3 ++- .../Physics/Engine/DefaultPhysicsEngine.cs | 1 + .../SystemGroup/CreateBallEntityCommandBufferSystem.cs | 2 +- .../Physics/SystemGroup/SimulateBuildSystem.cs | 3 ++- .../Physics/SystemGroup/SimulateCycleSystemGroup.cs | 3 ++- .../Physics/SystemGroup/TransformMeshesSystemGroup.cs | 2 +- .../Physics/SystemGroup/UpdateAnimationsSystemGroup.cs | 2 +- .../Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs | 2 +- .../VPT/Ball/BallDisplacementSystem.cs | 3 ++- .../VPT/Ball/BallLastPositionsBufferElement.cs | 2 +- .../VisualPinball.Unity/VPT/Ball/BallManager.cs | 1 + .../VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs | 6 ++++-- .../VPT/Ball/BallRingCounterSystem.cs | 3 ++- .../VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs | 3 ++- .../VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs | 3 ++- .../VPT/Bumper/BumperRingAnimationSystem.cs | 3 ++- .../VPT/Bumper/BumperRingMovementSystem.cs | 6 ++++-- .../VPT/Bumper/BumperSkirtAnimationSystem.cs | 3 ++- .../VPT/Bumper/BumperSkirtMovementSystem.cs | 3 ++- .../VisualPinball.Unity/VPT/CollidableApi.cs | 1 + .../VPT/Flipper/FlipperDisplacementSystem.cs | 3 ++- .../VPT/Flipper/FlipperRotateSystem.cs | 3 ++- .../VPT/Flipper/FlipperVelocitySystem.cs | 3 ++- .../VPT/Gate/GateDisplacementSystem.cs | 3 ++- .../VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs | 3 ++- .../VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs | 3 ++- .../VPT/HitTarget/DropTargetAnimationSystem.cs | 3 ++- .../VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs | 1 + .../VPT/HitTarget/DropTargetTransformationSystem.cs | 6 ++++-- .../VPT/HitTarget/HitTargetAnimationSystem.cs | 3 ++- .../VPT/HitTarget/HitTargetTransformationSystem.cs | 3 ++- VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs | 1 + .../VPT/Playfield/PlayfieldComponent.cs | 1 + .../VPT/Plunger/PlungerAnimationSystem.cs | 3 ++- .../VPT/Plunger/PlungerDisplacementSystem.cs | 3 ++- .../VPT/Plunger/PlungerTransformationSystem.cs | 3 ++- .../VPT/Plunger/PlungerVelocitySystem.cs | 9 +++++---- .../VPT/Spinner/SpinnerDisplacementSystem.cs | 3 ++- .../VPT/Spinner/SpinnerMovementSystem.cs | 3 ++- .../VPT/Spinner/SpinnerVelocitySystem.cs | 3 ++- .../VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs | 1 + .../VPT/Trigger/TriggerAnimationSystem.cs | 3 ++- .../VPT/Trigger/TriggerMovementSystem.cs | 6 ++++-- 53 files changed, 104 insertions(+), 52 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 71553c0e8..6b93b262d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -26,6 +26,7 @@ using VisualPinball.Engine.Game; using VisualPinball.Engine.Game.Engines; using VisualPinball.Engine.VPT.Trigger; +using VisualPinballUnity; using Logger = NLog.Logger; namespace VisualPinball.Unity diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs index 90ee21b34..6c0f5e0ce 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs @@ -19,6 +19,7 @@ using NLog; using Unity.Entities; using UnityEngine; +using VisualPinballUnity; using Logger = NLog.Logger; #if UNITY_EDITOR diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs index 22273b495..eab87a883 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs @@ -21,7 +21,7 @@ using Unity.Transforms; using VisualPinball.Engine.Common; -namespace VisualPinball.Unity +namespace VisualPinballUnity { /// /// Main physics simulation system, executed once per frame. diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs index ad6537442..1ef796fd3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs @@ -21,6 +21,7 @@ using UnityEngine; using UnityEngine.InputSystem; using NLog; +using VisualPinballUnity; using Logger = NLog.Logger; #if UNITY_EDITOR diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs index 79cd74549..60ef53ad3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs @@ -20,8 +20,10 @@ using Unity.Mathematics; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; +using Collider = UnityEngine.Collider; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class ContactSystem : SystemBase @@ -76,7 +78,7 @@ protected override void OnUpdate() if (collEvent.ColliderId > -1) { // collide with static collider ref var coll = ref colliders[collEvent.ColliderId].Value; unsafe { - fixed (Collider* collider = &coll) { + fixed (VisualPinball.Unity.Collider* collider = &coll) { // flipper contact updates movement data if (coll.Type == ColliderType.Flipper) { @@ -90,7 +92,7 @@ protected override void OnUpdate() SetComponent(coll.Entity, flipperMovementData); } else { - Collider.Contact(ref coll, ref ball, in collEvent, hitTime, in gravity); + VisualPinball.Unity.Collider.Contact(ref coll, ref ball, in collEvent, hitTime, in gravity); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs index 45f6c8d55..11ed95ca9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs @@ -17,8 +17,9 @@ using Unity.Collections; using Unity.Entities; using Unity.Profiling; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class DynamicBroadPhaseSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs index 39e2585fc..cc881d6a2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs @@ -16,8 +16,9 @@ using Unity.Entities; using Unity.Profiling; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class DynamicCollisionSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs index 9d7d4b642..d3ed59bf9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs @@ -16,8 +16,9 @@ using Unity.Entities; using Unity.Profiling; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class DynamicNarrowPhaseSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs index 66b134d8e..b2ecfa2fd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs @@ -16,8 +16,9 @@ using Unity.Entities; using Unity.Profiling; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class StaticBroadPhaseSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs index 4e1540be6..e961253e1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs @@ -21,10 +21,11 @@ using Unity.Entities; using Unity.Profiling; using VisualPinball.Engine.VPT; +using VisualPinball.Unity; using Object = UnityEngine.Object; using Random = UnityEngine.Random; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class StaticCollisionSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs index 8c84b5a78..7b2af9c1c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs @@ -19,8 +19,9 @@ using Unity.Mathematics; using Unity.Profiling; using VisualPinball.Engine.VPT; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class StaticNarrowPhaseSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs index a15ef6fc2..a5f3e7a95 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs @@ -21,6 +21,7 @@ using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Common; +using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs index bf5d7595e..a7e124867 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs @@ -16,7 +16,7 @@ using Unity.Entities; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal class CreateBallEntityCommandBufferSystem : EntityCommandBufferSystem diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs index a87ff22a1..8cf457fbc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs @@ -18,8 +18,9 @@ using Unity.Mathematics; using Unity.Transforms; using UnityEngine; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateBefore(typeof(TransformMeshesSystemGroup))] internal partial class SimulateBuildSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs index a849db4b0..e4f6759b6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs @@ -20,8 +20,9 @@ using Unity.Entities; using UnityEngine; using VisualPinball.Engine.Common; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { /// /// The main simulation loop diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs index e6e043895..9fdd1052f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs @@ -16,7 +16,7 @@ using Unity.Entities; -namespace VisualPinball.Unity +namespace VisualPinballUnity { internal partial class TransformMeshesSystemGroup : ComponentSystemGroup { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs index 7b7a40259..1a8038053 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs @@ -16,7 +16,7 @@ using Unity.Entities; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class UpdateAnimationsSystemGroup : ComponentSystemGroup diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs index 202d089f6..a04b04866 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs @@ -16,7 +16,7 @@ using Unity.Entities; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class UpdateVelocitiesSystemGroup : ComponentSystemGroup diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs index 2a9b91664..d87220570 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs @@ -18,8 +18,9 @@ using Unity.Mathematics; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] internal partial class BallDisplacementSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs index 338789778..98df7d768 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs @@ -17,7 +17,7 @@ using Unity.Entities; using Unity.Mathematics; -namespace VisualPinball.Unity +namespace VisualPinballUnity { /// /// The ball's last positions diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index 630653a79..8bf020e42 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -20,6 +20,7 @@ using UnityEngine; using VisualPinball.Engine.Common; using VisualPinball.Engine.Game; +using VisualPinballUnity; using Object = UnityEngine.Object; namespace VisualPinball.Unity diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs index 923971e04..0c69b5bf7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs @@ -18,8 +18,10 @@ using Unity.Mathematics; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; +using Physics = UnityEngine.Physics; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(TransformMeshesSystemGroup))] @@ -59,7 +61,7 @@ protected override void OnUpdate() // calculate/adapt height of ball var zHeight = !ball.IsFrozen ? ball.Position.z : ball.Position.z - ball.Radius; var ballTransform = _player.Balls[entity].transform; - ballTransform.localPosition = Physics.TranslateToWorld(ball.Position.x, ball.Position.y, zHeight); + ballTransform.localPosition = VisualPinball.Unity.Physics.TranslateToWorld(ball.Position.x, ball.Position.y, zHeight); var or = ball.BallOrientationForUnity; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs index 5ea155dc3..0bc767d65 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs @@ -16,8 +16,9 @@ using Unity.Entities; using VisualPinball.Engine.Common; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class BallRingCounterSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs index c507da3c7..98dda1527 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs @@ -17,8 +17,9 @@ using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [DisableAutoCreation] internal partial class BallSpinHackSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs index fd137a32e..001d1aee5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs @@ -21,8 +21,9 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Engine.Common; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] internal partial class BallVelocitySystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs index f3fe1601f..cf61b9e62 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs @@ -16,8 +16,9 @@ using Unity.Entities; using Unity.Profiling; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] internal partial class BumperRingAnimationSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs index 10963f5fc..24578f57a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs @@ -18,8 +18,10 @@ using Unity.Entities; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; +using Physics = UnityEngine.Physics; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] internal partial class BumperRingMovementSystem : SystemBase @@ -53,7 +55,7 @@ protected override void OnUpdate() var localOffset = localLimit / limit * data.Offset; var worldPos = transform.position; - worldPos.y = _initialOffset[entity] + Physics.ScaleToWorld(localOffset); + worldPos.y = _initialOffset[entity] + VisualPinball.Unity.Physics.ScaleToWorld(localOffset); transform.position = worldPos; marker.End(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs index 38ebbb21c..6dcacc3a9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs @@ -17,8 +17,9 @@ using Unity.Entities; using Unity.Mathematics; using Unity.Profiling; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] internal partial class BumperSkirtAnimationSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs index e18c71d4b..33383090f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs @@ -18,8 +18,9 @@ using Unity.Mathematics; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] internal partial class BumperSkirtMovementSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs index df61e5766..8a6a23291 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs @@ -18,6 +18,7 @@ using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT; +using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs index ee2cfea96..eeb617728 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs @@ -20,8 +20,9 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Engine.Game; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs index ef3d1b7c2..3a1b6d1c3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs @@ -18,8 +18,9 @@ using Unity.Mathematics; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(TransformMeshesSystemGroup))] diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs index 28fff190d..e2b76aeff 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs @@ -20,8 +20,9 @@ using Unity.Mathematics; using Unity.Profiling; using VisualPinball.Engine.Common; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs index e84f286c3..f50d4812e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs @@ -20,8 +20,9 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Engine.Game; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] internal partial class GateDisplacementSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs index bf97f4cd1..7466eadc4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs @@ -18,8 +18,9 @@ using Unity.Mathematics; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] internal partial class GateMovementSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs index d484ab4ec..f39cb59b6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs @@ -20,8 +20,9 @@ using Unity.Mathematics; using Unity.Profiling; using VisualPinball.Engine.Common; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] internal partial class GateVelocitySystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs index 0c3abd2ca..e3cd4939f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs @@ -19,8 +19,9 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Engine.Game; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] internal partial class DropTargetAnimationSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs index 5403695dd..dda9610aa 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs @@ -19,6 +19,7 @@ using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.HitTarget; +using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs index 63e257b9c..01de9cf8d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs @@ -17,8 +17,10 @@ using Unity.Entities; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; +using Physics = UnityEngine.Physics; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] internal partial class DropTargetTransformationSystem : SystemBase @@ -42,7 +44,7 @@ protected override void OnUpdate() var localPos = _player.DropTargetTransforms[entity].localPosition; _player.DropTargetTransforms[entity].localPosition = new Vector3( localPos.x, - Physics.ScaleToWorld(data.ZOffset), + VisualPinball.Unity.Physics.ScaleToWorld(data.ZOffset), localPos.z ); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs index 465206091..e53643af6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs @@ -17,8 +17,9 @@ using Unity.Collections; using Unity.Entities; using Unity.Profiling; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] internal partial class HitTargetAnimationSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs index ac4ca81bd..119b585c3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs @@ -17,8 +17,9 @@ using Unity.Entities; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] internal partial class HitTargetTransformationSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs index 91d2a1c98..5e5677f48 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs @@ -17,6 +17,7 @@ using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT; +using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs index 5e29539df..0c91e51e5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs @@ -28,6 +28,7 @@ using VisualPinball.Engine.VPT.Primitive; using VisualPinball.Engine.VPT.Table; using VisualPinball.Unity.Playfield; +using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs index 2e6f0db32..8d510e8ef 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs @@ -17,8 +17,9 @@ using Unity.Entities; using Unity.Mathematics; using Unity.Profiling; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] internal partial class PlungerAnimationSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs index 9c4ae5e03..1b78f020e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs @@ -20,8 +20,9 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Engine.Game; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] internal partial class PlungerDisplacementSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs index d62c837df..beb21ce0c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs @@ -17,8 +17,9 @@ using Unity.Entities; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] internal partial class PlungerTransformationSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs index 7e0c1d500..559a5900c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs @@ -16,8 +16,9 @@ using Unity.Entities; using Unity.Profiling; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] internal partial class PlungerVelocitySystem : SystemBase @@ -148,7 +149,7 @@ protected override void OnUpdate() // but we can elide the elapsed time factor because it's // effectively a constant that's implicitly folded into the // pull force value. - movementData.Speed += velocityData.PullForce / Engine.VPT.Plunger.Plunger.PlungerMass; + movementData.Speed += velocityData.PullForce / VisualPinball.Engine.VPT.Plunger.Plunger.PlungerMass; if (!velocityData.AddRetractMotion) { // this is the normal PullBack branch @@ -311,10 +312,10 @@ protected override void OnUpdate() // runs physics frames at roughly 10x the rate of VP 9, so the time // per frame is about 1/10 the VP 9 time. const float plungerFriction = 0.95f; - const float normalize = Engine.VPT.Plunger.Plunger.PlungerNormalize / 13.0f / 100.0f; + const float normalize = VisualPinball.Engine.VPT.Plunger.Plunger.PlungerNormalize / 13.0f / 100.0f; const float dt = 0.1f; movementData.Speed *= plungerFriction; - movementData.Speed += error * staticData.FrameLen * velocityData.MechStrength / Engine.VPT.Plunger.Plunger.PlungerMass * normalize * dt; + movementData.Speed += error * staticData.FrameLen * velocityData.MechStrength / VisualPinball.Engine.VPT.Plunger.Plunger.PlungerMass * normalize * dt; // add any reverse impulse to the result movementData.Speed += movementData.ReverseImpulse; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs index def3a3627..1048f7a11 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs @@ -22,8 +22,9 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Engine.Game; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] internal partial class SpinnerDisplacementSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs index 487109924..490602992 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs @@ -18,8 +18,9 @@ using Unity.Mathematics; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] internal partial class SpinnerMovementSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs index 9ff2c88f1..76b1bd012 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs @@ -18,8 +18,9 @@ using Unity.Mathematics; using Unity.Profiling; using VisualPinball.Engine.Common; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] internal partial class SpinnerVelocitySystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs index 3f71d0605..a456d1b4c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs @@ -22,6 +22,7 @@ using Unity.Entities; using Unity.Mathematics; using UnityEngine; +using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs index 844ee1db0..1ee0be4e6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs @@ -17,8 +17,9 @@ using Unity.Entities; using Unity.Profiling; using VisualPinball.Engine.VPT; +using VisualPinball.Unity; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] internal partial class TriggerAnimationSystem : SystemBase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs index 5f176f1c7..8643e2039 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs @@ -18,8 +18,10 @@ using Unity.Entities; using Unity.Profiling; using UnityEngine; +using VisualPinball.Unity; +using Physics = UnityEngine.Physics; -namespace VisualPinball.Unity +namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] internal partial class TriggerMovementSystem : SystemBase @@ -49,7 +51,7 @@ protected override void OnUpdate() } var worldPos = transform.position; - worldPos.y = _initialOffset[entity] + Physics.ScaleToWorld(data.HeightOffset); + worldPos.y = _initialOffset[entity] + VisualPinball.Unity.Physics.ScaleToWorld(data.HeightOffset); transform.position = worldPos; marker.End(); From 103a5b83dbf7fe426b539a0bf4054ffa7bbb9b17 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 10 Jan 2023 00:25:33 +0100 Subject: [PATCH 018/159] dots: Add subscene when importing VPX. --- .../Import/VpxSceneConverter.cs | 39 +++++++++++++++++-- .../VisualPinball.Unity.Editor.asmdef | 1 + 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs index b55130cc9..967315eae 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs @@ -20,6 +20,7 @@ using System.Linq; using System.Reflection; using NLog; +using Unity.Scenes; using UnityEditor; using UnityEditor.Formats.Fbx.Exporter; using UnityEditor.SceneManagement; @@ -572,7 +573,23 @@ private void CreateRootHierarchy(string tableName = null) .Replace("%TABLENAME%", _sourceTable.Name) .Replace("%INFONAME%", _sourceContainer.InfoName); } - + + // 1. generate table scene + var tableScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive); + var scenePath = GetScenePath(tableName); + tableScene.name = tableName; + EditorSceneManager.SaveScene(tableScene, scenePath); + EditorSceneManager.CloseScene(tableScene, true); + + // 2. link table scene as sub scene + var subSceneGo = new GameObject(tableName); + var subSceneMb = subSceneGo.AddComponent(); + var subSceneAsset = AssetDatabase.LoadAssetAtPath(scenePath); + subSceneMb.SceneAsset = subSceneAsset; + tableScene = EditorSceneManager.OpenScene(scenePath); + SceneManager.SetActiveScene(tableScene); + + // 3. create game object hierarchy _tableGo = new GameObject(tableName); _playfieldGo = new GameObject("Playfield"); var backglassGo = new GameObject("Backglass"); @@ -585,16 +602,30 @@ private void CreateRootHierarchy(string tableName = null) backglassGo.transform.SetParent(_tableGo.transform, false); cabinetGo.transform.SetParent(_tableGo.transform, false); + // 4. add components _playfieldComponent = _playfieldGo.AddComponent(); _playfieldGo.AddComponent(); _playfieldGo.AddComponent(); _playfieldGo.AddComponent(); - //_playfieldGo.transform.localRotation = PlayfieldComponent.GlobalRotation; - //_playfieldGo.transform.localPosition = new Vector3(-_sourceTable.Width / 2 * PlayfieldComponent.GlobalScale, 0f, _sourceTable.Height / 2 * PlayfieldComponent.GlobalScale); - //_playfieldGo.transform.localScale = new Vector3(PlayfieldComponent.GlobalScale, PlayfieldComponent.GlobalScale, PlayfieldComponent.GlobalScale); _playfieldComponent.SetData(_sourceTable.Data); } + private static string GetScenePath(string tableName) + { + const string sceneRoot = "Assets/Tables/"; + var i = -1; + do { + var suffix = i >= 0 ? "." + i.ToString("D3") : ""; + var scenePath = $"{sceneRoot}{tableName}{suffix}.unity"; + if (!File.Exists(scenePath)) { + return scenePath; + } + i++; + } while (i < 999); + + return null; + } + private GameObject GetGroupParent(IItem item) => GetGroupParent(item.ItemGroupName); public GameObject GetGroupParent(string name) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.asmdef b/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.asmdef index 1cbf50624..04f6b9d53 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.asmdef +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.asmdef @@ -8,6 +8,7 @@ "Unity.Mathematics", "Unity.Transforms", "Unity.InputSystem", + "Unity.Scenes", "VisualPinball.Engine", "VisualPinball.Unity", "VisualPinball.Unity.Patcher" From 6fd6c761bc01f0b89d0175fa8d02342637d0dce0 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 11 Jan 2023 00:11:36 +0100 Subject: [PATCH 019/159] dots: Subscene import works, with errors. --- .../Import/VpxMenuImporter.cs | 27 ++++++++++++ .../Import/VpxSceneConverter.cs | 42 +++++++++++-------- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxMenuImporter.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxMenuImporter.cs index 30b1f7007..7292c8c88 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxMenuImporter.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxMenuImporter.cs @@ -20,6 +20,8 @@ using System.IO; using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine.SceneManagement; namespace VisualPinball.Unity.Editor { @@ -28,6 +30,11 @@ public static class VpxMenuImporter [MenuItem("Visual Pinball/Import VPX", false, 2)] public static void ImportVpxIntoScene(MenuCommand menuCommand) { + // if it's an untitled scene, save first. + if (!EnsureUntitledSceneHasBeenSaved("Before importing, you need to make your current scene an asset by saving it.")) { + return; + } + // open file dialog var vpxPath = EditorUtility.OpenFilePanelWithFilters("Import .VPX File", null, new[] { "Visual Pinball Table Files", "vpx" }); if (vpxPath.Length == 0) { @@ -36,5 +43,25 @@ public static void ImportVpxIntoScene(MenuCommand menuCommand) VpxImportEngine.ImportIntoScene(vpxPath, tableName: Path.GetFileNameWithoutExtension(vpxPath)); } + + private static bool EnsureUntitledSceneHasBeenSaved(string message) + { + if (string.IsNullOrEmpty(SceneManager.GetActiveScene().path)) { + + if (!EditorUtility.DisplayDialog("Info", "Before importing, you need to make your current scene an asset by saving it.\nSave your current scene?", "Yes", "No")) { + return false; + } + + // Ask the user to save + EditorSceneManager.SaveOpenScenes(); + + // Check that the scene was saved + if (!string.IsNullOrEmpty(SceneManager.GetActiveScene().path)) { + return true; + } + return false; + } + return true; + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs index 967315eae..e6a2083d0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs @@ -67,6 +67,7 @@ public class VpxSceneConverter : ITextureProvider, IMaterialProvider, IMeshProvi private readonly Table _sourceTable; private readonly ConvertOptions _options; + private Scene _tableScene; private GameObject _tableGo; private TableComponent _tableComponent; private PlayfieldComponent _playfieldComponent; @@ -168,9 +169,8 @@ public GameObject Convert(bool applyPatch = true, string tableName = null) _patcher?.PostPatch(_tableGo); } - return _tableGo; + return MakeSubScene(); } - private void SaveData() { foreach (var key in _sourceContainer.TableInfo.Keys) { @@ -574,22 +574,12 @@ private void CreateRootHierarchy(string tableName = null) .Replace("%INFONAME%", _sourceContainer.InfoName); } - // 1. generate table scene - var tableScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive); - var scenePath = GetScenePath(tableName); - tableScene.name = tableName; - EditorSceneManager.SaveScene(tableScene, scenePath); - EditorSceneManager.CloseScene(tableScene, true); - - // 2. link table scene as sub scene - var subSceneGo = new GameObject(tableName); - var subSceneMb = subSceneGo.AddComponent(); - var subSceneAsset = AssetDatabase.LoadAssetAtPath(scenePath); - subSceneMb.SceneAsset = subSceneAsset; - tableScene = EditorSceneManager.OpenScene(scenePath); - SceneManager.SetActiveScene(tableScene); + // 1. create table scene + _tableScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive); + _tableScene.name = tableName; + SceneManager.SetActiveScene(_tableScene); - // 3. create game object hierarchy + // 2. create game object hierarchy _tableGo = new GameObject(tableName); _playfieldGo = new GameObject("Playfield"); var backglassGo = new GameObject("Backglass"); @@ -602,13 +592,29 @@ private void CreateRootHierarchy(string tableName = null) backglassGo.transform.SetParent(_tableGo.transform, false); cabinetGo.transform.SetParent(_tableGo.transform, false); - // 4. add components + // 3. add components _playfieldComponent = _playfieldGo.AddComponent(); _playfieldGo.AddComponent(); _playfieldGo.AddComponent(); _playfieldGo.AddComponent(); _playfieldComponent.SetData(_sourceTable.Data); } + + private GameObject MakeSubScene() + { + var sceneName = _tableScene.name; + var scenePath = GetScenePath(sceneName); + EditorSceneManager.SaveScene(_tableScene, scenePath); + EditorSceneManager.CloseScene(_tableScene, true); + + // link table scene as sub scene + var subSceneGo = new GameObject(sceneName); + var subSceneMb = subSceneGo.AddComponent(); + var subSceneAsset = AssetDatabase.LoadAssetAtPath(scenePath); + subSceneMb.SceneAsset = subSceneAsset; + + return subSceneGo; + } private static string GetScenePath(string tableName) { From 588b747e5f74c25dbd531b574356f53e22875acd Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 16 Jan 2023 00:27:06 +0100 Subject: [PATCH 020/159] dots: Remove ConvertToEntity from prefabs. --- .../Resources/Prefabs/Bumper (Builtin).prefab | 14 --- .../Prefabs/Drop Target (Builtin).prefab | 18 +-- .../Assets/Resources/Prefabs/Flipper.prefab | 113 ++++++------------ .../Resources/Prefabs/Gate (Builtin).prefab | 19 +-- .../Prefabs/Hit Target (Builtin).prefab | 20 +--- .../Resources/Prefabs/Kicker (Builtin).prefab | 19 +-- .../Resources/Prefabs/MetalWireGuide.prefab | 17 +-- .../Assets/Resources/Prefabs/Plunger.prefab | 91 +++----------- .../Assets/Resources/Prefabs/Primitive.prefab | 93 ++------------ .../Assets/Resources/Prefabs/Ramp.prefab | 97 ++++----------- .../Assets/Resources/Prefabs/Rubber.prefab | 18 +-- .../Prefabs/Spinner (Builtin).prefab | 19 +-- .../Assets/Resources/Prefabs/Surface.prefab | 19 +-- .../Assets/Resources/Prefabs/Trigger.prefab | 15 +-- 14 files changed, 120 insertions(+), 452 deletions(-) diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Bumper (Builtin).prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Bumper (Builtin).prefab index cd97280fa..8d67014d0 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Bumper (Builtin).prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Bumper (Builtin).prefab @@ -11,7 +11,6 @@ GameObject: - component: {fileID: 8936098568141045026} - component: {fileID: 197865258511769274} - component: {fileID: 1813312543483188556} - - component: {fileID: 558255656085877858} m_Layer: 0 m_Name: Bumper (Builtin) m_TagString: Untagged @@ -78,19 +77,6 @@ MonoBehaviour: Force: 15 Scatter: 0 HitEvent: 1 ---- !u!114 &558255656085877858 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 642515788050218447} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 --- !u!1 &2782857395794746971 GameObject: m_ObjectHideFlags: 0 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Drop Target (Builtin).prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Drop Target (Builtin).prefab index b7d0cf601..eabdb6e38 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Drop Target (Builtin).prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Drop Target (Builtin).prefab @@ -14,7 +14,6 @@ GameObject: - component: {fileID: -6600741874494028717} - component: {fileID: 8307013672536159350} - component: {fileID: 16544014384142367} - - component: {fileID: 531720702824142340} m_Layer: 0 m_Name: Drop Target (Builtin) m_TagString: Untagged @@ -32,6 +31,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 @@ -56,7 +56,7 @@ MonoBehaviour: Rotation: 0 Size: {x: 32, y: 32, z: 32} _targetType: 1 - MeshName: + _meshName: --- !u!114 &-7285854734489305104 MonoBehaviour: m_ObjectHideFlags: 0 @@ -114,6 +114,7 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 @@ -144,16 +145,3 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &531720702824142340 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4811490838886355864} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Flipper.prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Flipper.prefab index d8aa8491e..02ccd6d9e 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Flipper.prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Flipper.prefab @@ -28,6 +28,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4440381279647306322} m_RootOrder: 1 @@ -44,7 +45,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 8e6fc321830c03547890119a04997404, type: 3} m_Name: m_EditorClassIdentifier: - _meshCreated: 1 + _instanceID: 45420 --- !u!33 &4778019510121147183 MeshFilter: m_ObjectHideFlags: 0 @@ -81,6 +82,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 4440381279647306322} m_RootOrder: 0 @@ -97,7 +99,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 89e3c1c147bb7a049b0510709f1ad9f2, type: 3} m_Name: m_EditorClassIdentifier: - _meshCreated: 1 + _instanceID: 45406 --- !u!33 &8383588224779965405 MeshFilter: m_ObjectHideFlags: 0 @@ -117,7 +119,6 @@ GameObject: - component: {fileID: 4440381279647306322} - component: {fileID: 2330311059251221068} - component: {fileID: 8750544366699972018} - - component: {fileID: 3449526034131864867} m_Layer: 0 m_Name: Flipper m_TagString: Untagged @@ -135,6 +136,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 5879026712924827105} - {fileID: 6818887475746504221} @@ -153,73 +155,26 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 545ad741f74d2444faf5d2882fba6b69, type: 3} m_Name: m_EditorClassIdentifier: - _data: - StoragePrefix: 0 - StorageIndex: 0 - IsLocked: 0 - EditorLayerName: - EditorLayerVisibility: 0 - Name: - BaseRadius: 0 - EndRadius: 0 - FlipperRadiusMin: 0 - FlipperRadiusMax: 0 - FlipperRadius: 0 - StartAngle: 0 - EndAngle: 0 - Height: 0 - Center: - X: 0 - Y: 0 - Image: - Surface: - Material: - RubberMaterial: - RubberThickness: 0 - RubberHeight: 0 - RubberWidth: 0 - Mass: 0 - Strength: 0 - Elasticity: 0 - ElasticityFalloff: 0 - Friction: 0 - Return: 0 - RampUp: 0 - TorqueDamping: 0 - TorqueDampingAngle: 0 - Scatter: 0 - OverridePhysics: 0 - IsVisible: 0 - IsEnabled: 0 - IsReflectionEnabled: 0 - IsTimerEnabled: 0 - TimerInterval: 0 - IsDualWound: 0 - OverrideMass: 0 - OverrideStrength: 0 - OverrideElasticity: 0 - OverrideElasticityFalloff: 0 - OverrideFriction: 0 - OverrideReturnStrength: 0 - OverrideCoilRampUp: 0 - OverrideTorqueDamping: 0 - OverrideTorqueDampingAngle: 0 - OverrideScatterAngle: 0 + _isLocked: 0 + _editorLayer: 0 + _editorLayerName: + _editorLayerVisibility: 1 Position: {x: 0, y: 0} - StartAngle: 121 + _startAngle: 121 EndAngle: 70 _surface: {fileID: 0} IsEnabled: 1 IsDualWound: 0 - Height: 50 - BaseRadius: 21.5 - EndRadius: 13 + _height: 50 + _baseRadius: 21.5 + _endRadius: 13 FlipperRadiusMin: 0 FlipperRadiusMax: 130 - FlipperRadius: 130 - RubberThickness: 7 - RubberHeight: 19 - RubberWidth: 24 + _rubberThickness: 7 + _rubberHeight: 19 + _rubberWidth: 24 + InstantiateAsPrefab: 0 + _originalRotateZ: 0 --- !u!114 &8750544366699972018 MonoBehaviour: m_ObjectHideFlags: 0 @@ -233,7 +188,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: PhysicsMaterial: {fileID: 0} - ShowColliderMesh: 0 + ShowColliderMesh: 1 ShowAabbs: 0 Mass: 1 Strength: 2200 @@ -246,16 +201,20 @@ MonoBehaviour: TorqueDampingAngle: 6 Scatter: 0 FlipperCorrection: {fileID: 11400000, guid: f8799be363ab20a459dd185669ece8aa, type: 2} ---- !u!114 &3449526034131864867 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8904124417643437867} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 + useFlipperTricksPhysics: 0 + SOSRampUp: 2.5 + SOSEM: 0.85 + EOSReturn: 0.055 + EOSTNew: 0.8 + EOSANew: 1 + EOSRampup: 0 + Overshoot: 3 + BumpOnRelease: 0.4 + useFlipperLiveCatch: 0 + LiveCatchDistanceMin: 40 + LiveCatchDistanceMax: 100 + LiveCatchMinimalBallSpeed: 6 + LiveCatchFullTime: 16 + LiveCatchPerfectTime: 8 + LiveCatchMinmalBounceSpeedMultiplier: 0.1 + LiveCatchInaccurateBounceSpeedMultiplier: 1 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Gate (Builtin).prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Gate (Builtin).prefab index 2e7a48fcc..fe25f4acf 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Gate (Builtin).prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Gate (Builtin).prefab @@ -11,7 +11,6 @@ GameObject: - component: {fileID: 7014708109448554416} - component: {fileID: 3468265542873711340} - component: {fileID: 3496935618586042827} - - component: {fileID: -7170736425438619631} m_Layer: 0 m_Name: Gate (Builtin) m_TagString: Gate @@ -29,6 +28,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 6622806185196320941} - {fileID: 2980705729845053989} @@ -79,19 +79,6 @@ MonoBehaviour: Friction: 0.02 GravityFactor: 0.25 _twoWay: 0 ---- !u!114 &-7170736425438619631 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4689510019247135382} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 --- !u!1 &6497995796854627700 GameObject: m_ObjectHideFlags: 0 @@ -120,6 +107,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7014708109448554416} m_RootOrder: 0 @@ -143,6 +131,7 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 @@ -202,6 +191,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 7014708109448554416} m_RootOrder: 1 @@ -237,6 +227,7 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Hit Target (Builtin).prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Hit Target (Builtin).prefab index f63962e24..93a9ec8c5 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Hit Target (Builtin).prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Hit Target (Builtin).prefab @@ -14,7 +14,6 @@ GameObject: - component: {fileID: 2121126026550932934} - component: {fileID: 8307013672536159350} - component: {fileID: 16544014384142367} - - component: {fileID: 531720702824142340} m_Layer: 0 m_Name: Hit Target (Builtin) m_TagString: Untagged @@ -32,6 +31,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 @@ -56,7 +56,7 @@ MonoBehaviour: Rotation: 0 Size: {x: 32, y: 32, z: 32} _targetType: 1 - MeshName: + _meshName: --- !u!114 &-1267520440965682989 MonoBehaviour: m_ObjectHideFlags: 0 @@ -76,10 +76,8 @@ MonoBehaviour: ElasticityFalloff: 0.5 Friction: 0.2 Scatter: 5 - IsLegacy: 0 OverwritePhysics: 1 Threshold: 2 - UseHitEvent: 1 --- !u!114 &2121126026550932934 MonoBehaviour: m_ObjectHideFlags: 0 @@ -113,6 +111,7 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 @@ -143,16 +142,3 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &531720702824142340 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4811490838886355864} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Kicker (Builtin).prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Kicker (Builtin).prefab index 7abd36679..4a9295d9e 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Kicker (Builtin).prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Kicker (Builtin).prefab @@ -13,7 +13,6 @@ GameObject: - component: {fileID: -2035473210646026864} - component: {fileID: 2254716409977562185} - component: {fileID: 9085684073653883757} - - component: {fileID: 5688332318531931923} m_Layer: 0 m_Name: Kicker (Builtin) m_TagString: Untagged @@ -31,6 +30,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 @@ -82,9 +82,8 @@ MonoBehaviour: HitAccuracy: 0.7 HitHeight: 40 FallThrough: 0 + FallIn: 1 LegacyMode: 1 - EjectAngle: 90 - EjectSpeed: 3 --- !u!33 &2254716409977562185 MeshFilter: m_ObjectHideFlags: 0 @@ -104,6 +103,7 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 @@ -134,16 +134,3 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!114 &5688332318531931923 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2420819360404407618} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/MetalWireGuide.prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/MetalWireGuide.prefab index 5efa4de90..453c0dfc0 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/MetalWireGuide.prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/MetalWireGuide.prefab @@ -13,7 +13,6 @@ GameObject: - component: {fileID: 2107529826525245329} - component: {fileID: -3250516992663423584} - component: {fileID: 4392546155774236836} - - component: {fileID: 171621741425913877} m_Layer: 0 m_Name: MetalWireGuide m_TagString: Untagged @@ -54,7 +53,9 @@ MonoBehaviour: _editorLayerVisibility: 1 _height: 25 _thickness: 8 + _standheight: 30 Rotation: {x: 0, y: 0, z: 0} + _bendradius: 8 _dragPoints: [] --- !u!114 &2107529826525245329 MonoBehaviour: @@ -90,6 +91,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: bcc8f0e761a7bc145abb5a6f918953aa, type: 3} m_Name: m_EditorClassIdentifier: + _instanceID: 46096 --- !u!33 &4392546155774236836 MeshFilter: m_ObjectHideFlags: 0 @@ -98,16 +100,3 @@ MeshFilter: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5446999501863086646} m_Mesh: {fileID: 0} ---- !u!114 &171621741425913877 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5446999501863086646} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Plunger.prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Plunger.prefab index 0488ff1f4..cfce987e3 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Plunger.prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Plunger.prefab @@ -11,7 +11,6 @@ GameObject: - component: {fileID: 2688967276888975725} - component: {fileID: 8461769246571476234} - component: {fileID: 4360165373544367127} - - component: {fileID: 6380137805125368953} m_Layer: 0 m_Name: Plunger m_TagString: Untagged @@ -29,6 +28,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 2983885423002777819} - {fileID: 1501205072833867318} @@ -47,65 +47,14 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: c1591b5a0bc15604fb622d417b509185, type: 3} m_Name: m_EditorClassIdentifier: - _data: - StoragePrefix: 0 - StorageIndex: -1 - IsLocked: 0 - EditorLayerName: - EditorLayerVisibility: 1 - Name: - Type: 1 - Center: - X: 0 - Y: 0 - Width: 25 - Height: 20 - ZAdjust: 0 - Stroke: 80 - SpeedPull: 0.5 - SpeedFire: 80 - MechStrength: 85 - ParkPosition: 0.16666667 - ScatterVelocity: 0 - MomentumXfer: 1 - IsMechPlunger: 0 - AutoPlunger: 0 - AnimFrames: 1 - Material: - Image: - IsVisible: 1 - IsReflectionEnabled: 1 - Surface: - TipShape: 0 .34; 2 .6; 3 .64; 5 .7; 7 .84; 8 .88; 9 .9; 11 .92; 14 .92; 39 .84 - RodDiam: 0.6 - RingGap: 2 - RingDiam: 0.94 - RingWidth: 3 - SpringDiam: 0.77 - SpringGauge: 1.38 - SpringLoops: 8 - SpringEndLoops: 2.5 - IsTimerEnabled: 0 - TimerInterval: 0 - Color: - Red: 207 - Green: 196 - Blue: 196 - Alpha: 4 + _isLocked: 0 + _editorLayer: 0 + _editorLayerName: + _editorLayerVisibility: 1 Position: {x: 0, y: 0} Width: 25 Height: 20 - ParkPosition: 0.16666667 - MomentumXfer: 1 - ScatterVelocity: 0 - IsAutoPlunger: 0 - IsMechPlunger: 0 - SpeedFire: 80 - Type: 1 ZAdjust: 0 - Stroke: 80 - SpeedPull: 0.5 - MechStrength: 85 _surface: {fileID: 0} analogPlungerAction: {fileID: 0} --- !u!114 &4360165373544367127 @@ -121,21 +70,17 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: PhysicsMaterial: {fileID: 0} - ShowColliderMesh: 0 + ShowColliderMesh: 1 ShowAabbs: 0 ---- !u!114 &6380137805125368953 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3492958815385962431} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 + SpeedPull: 0.5 + SpeedFire: 80 + Stroke: 80 + ScatterVelocity: 0 + IsMechPlunger: 0 + IsAutoPlunger: 0 + MechStrength: 85 + MomentumXfer: 1 + ParkPosition: 0.16666667 --- !u!1 &3501041183407321805 GameObject: m_ObjectHideFlags: 0 @@ -164,6 +109,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2688967276888975725} m_RootOrder: 1 @@ -180,7 +126,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 8506b0486aacff543b92dd7de914f936, type: 3} m_Name: m_EditorClassIdentifier: - _meshCreated: 1 + _instanceID: 46138 SpringDiam: 0.77 SpringGauge: 1.38 SpringLoops: 8 @@ -221,6 +167,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2688967276888975725} m_RootOrder: 0 @@ -237,7 +184,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 6e7622b4c6837354c8190ee471830c31, type: 3} m_Name: m_EditorClassIdentifier: - _meshCreated: 1 + _instanceID: 46132 RodDiam: 0.6 RingGap: 2 RingDiam: 0.94 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Primitive.prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Primitive.prefab index cc743d002..74875c1ac 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Primitive.prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Primitive.prefab @@ -13,7 +13,6 @@ GameObject: - component: {fileID: 8623744740865740302} - component: {fileID: -1370878250268705008} - component: {fileID: 9164173217974165609} - - component: {fileID: 4695815590852492947} m_Layer: 0 m_Name: Primitive m_TagString: Untagged @@ -31,6 +30,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 @@ -47,80 +47,16 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 151fb873f4d60994e8bde3aff9af4ca2, type: 3} m_Name: m_EditorClassIdentifier: - _data: - StoragePrefix: 0 - StorageIndex: -1 - IsLocked: 0 - EditorLayerName: - EditorLayerVisibility: 1 - Name: - Position: - X: 0 - Y: 0 - Z: 0 - Size: - X: 100 - Y: 100 - Z: 100 - NumVertices: 0 - CompressedVertices: 0 - NumIndices: 0 - CompressedIndices: 0 - CompressedAnimationVertices: - Mesh: - Name: - Vertices: [] - Indices: - AnimationDefaultPosition: 0 - RotAndTra: - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - - 0 - Image: - NormalMap: - Sides: 4 - Material: - SideColor: - Red: 0 - Green: 0 - Blue: 0 - Alpha: 0 - IsVisible: 1 - IsReflectionEnabled: 1 - DrawTexturesInside: 0 - HitEvent: 1 - Threshold: 2 - Elasticity: 0.3 - ElasticityFalloff: 0.5 - Friction: 0.3 - Scatter: 0 - EdgeFactorUi: 0.25 - CollisionReductionFactor: 0 - IsCollidable: 1 - IsToy: 0 - PhysicsMaterial: - OverwritePhysics: 1 - StaticRendering: 1 - DisableLightingTop: 0 - DisableLightingBelow: 0 - Use3DMesh: 0 - BackfacesEnabled: 0 - DisplayTexture: 0 - ObjectSpaceNormalMap: 0 - MeshFileName: - DepthBias: 0 + _isLocked: 0 + _editorLayer: 0 + _editorLayerName: + _editorLayerVisibility: 1 Position: {x: 0, y: 0, z: 0} Rotation: {x: 0, y: 0, z: 0} Size: {x: 1, y: 1, z: 1} Translation: {x: 0, y: 0, z: 0} ObjectRotation: {x: 0, y: 0, z: 0} - StaticRendering: 1 + _originalRotateZ: 0 --- !u!114 &8623744740865740302 MonoBehaviour: m_ObjectHideFlags: 0 @@ -134,7 +70,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: PhysicsMaterial: {fileID: 0} - ShowColliderMesh: 0 + ShowColliderMesh: 1 ShowAabbs: 0 HitEvent: 1 Threshold: 2 @@ -156,7 +92,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 882edbbe53953ef4ab3b3f846c4a5d9a, type: 3} m_Name: m_EditorClassIdentifier: - _meshCreated: 1 + _instanceID: 46174 UseLegacyMesh: 0 Sides: 4 --- !u!33 &9164173217974165609 @@ -167,16 +103,3 @@ MeshFilter: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5926445367393707725} m_Mesh: {fileID: 0} ---- !u!114 &4695815590852492947 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5926445367393707725} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Ramp.prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Ramp.prefab index 7622a8682..929d78ff4 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Ramp.prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Ramp.prefab @@ -28,6 +28,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3438007474298596154} m_RootOrder: 0 @@ -44,7 +45,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 96191c0bd78913d4da1df786720fbffd, type: 3} m_Name: m_EditorClassIdentifier: - _meshCreated: 1 + _instanceID: 46210 --- !u!33 &2139504653030743311 MeshFilter: m_ObjectHideFlags: 0 @@ -64,7 +65,6 @@ GameObject: - component: {fileID: 3438007474298596154} - component: {fileID: -2655459220674085019} - component: {fileID: -7808509646302655205} - - component: {fileID: 1745434368933653034} m_Layer: 0 m_Name: Ramp m_TagString: Untagged @@ -82,6 +82,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 6727185824501835254} - {fileID: 424251909686763979} @@ -101,56 +102,21 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: a5ac226119aa7a6458cda67c68713b3a, type: 3} m_Name: m_EditorClassIdentifier: - _data: - StoragePrefix: 0 - StorageIndex: -1 - IsLocked: 0 - EditorLayerName: - EditorLayerVisibility: 1 - Name: - DepthBias: 0 - DragPoints: [] - Elasticity: 0 - Friction: 0 - HitEvent: 0 - HeightBottom: 0 - HeightTop: 50 - ImageAlignment: 0 - ImageWalls: 1 - IsCollidable: 1 - IsReflectionEnabled: 1 - IsVisible: 1 - LeftWallHeight: 62 - LeftWallHeightVisible: 30 - OverwritePhysics: 1 - RampType: 0 - RightWallHeight: 62 - RightWallHeightVisible: 30 - Scatter: 0 - Image: - Material: - PhysicsMaterial: - Threshold: 0 - WidthBottom: 75 - WidthTop: 60 - WireDiameter: 8 - WireDistanceX: 38 - WireDistanceY: 88 - IsTimerEnabled: 0 - TimerInterval: 0 - Points: 0 - Type: 0 - HeightBottom: 0 - HeightTop: 50 - ImageAlignment: 0 - ImageWalls: 1 - LeftWallHeightVisible: 30 - RightWallHeightVisible: 30 - WidthBottom: 75 - WidthTop: 60 - WireDiameter: 8 - WireDistanceX: 38 - WireDistanceY: 88 + _isLocked: 0 + _editorLayer: 0 + _editorLayerName: + _editorLayerVisibility: 1 + _type: 0 + _heightBottom: 0 + _heightTop: 50 + _imageAlignment: 0 + _leftWallHeightVisible: 30 + _rightWallHeightVisible: 30 + _widthBottom: 75 + _widthTop: 60 + _wireDiameter: 8 + _wireDistanceX: 38 + _wireDistanceY: 88 _dragPoints: [] --- !u!114 &-7808509646302655205 MonoBehaviour: @@ -165,29 +131,16 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: PhysicsMaterial: {fileID: 0} - ShowColliderMesh: 0 + ShowColliderMesh: 1 ShowAabbs: 0 + HitEvent: 0 + Threshold: 0 LeftWallHeight: 62 RightWallHeight: 62 + OverwritePhysics: 1 Elasticity: 0 Friction: 0 - HitEvent: 0 - OverwritePhysics: 1 Scatter: 0 - Threshold: 0 ---- !u!114 &1745434368933653034 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 350393708356709200} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 --- !u!1 &378628362425001625 GameObject: m_ObjectHideFlags: 0 @@ -216,6 +169,7 @@ Transform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3438007474298596154} m_RootOrder: 1 @@ -232,7 +186,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 4f415a8bce1d6404e914122b72e420ca, type: 3} m_Name: m_EditorClassIdentifier: - _meshCreated: 1 + _instanceID: 46220 --- !u!33 &7529751573154737776 MeshFilter: m_ObjectHideFlags: 0 @@ -269,6 +223,7 @@ Transform: m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 3438007474298596154} m_RootOrder: 2 @@ -285,7 +240,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: fb775e2709cbb994e8b981aad06a08c2, type: 3} m_Name: m_EditorClassIdentifier: - _meshCreated: 1 + _instanceID: 46218 --- !u!33 &5184614959798449138 MeshFilter: m_ObjectHideFlags: 0 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Rubber.prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Rubber.prefab index 767c1f5e1..47ecdf995 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Rubber.prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Rubber.prefab @@ -13,7 +13,6 @@ GameObject: - component: {fileID: -4932743686767062960} - component: {fileID: 3941825256112358932} - component: {fileID: 4392546155774236836} - - component: {fileID: 171621741425913877} m_Layer: 0 m_Name: Rubber m_TagString: Untagged @@ -31,6 +30,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 @@ -52,7 +52,6 @@ MonoBehaviour: _editorLayerName: _editorLayerVisibility: 1 _height: 25 - _hitHeight: 25 _thickness: 8 Rotation: {x: 0, y: 0, z: 0} _dragPoints: [] @@ -72,6 +71,7 @@ MonoBehaviour: ShowColliderMesh: 1 ShowAabbs: 0 HitEvent: 0 + HitHeight: 25 OverwritePhysics: 0 Elasticity: 0 ElasticityFalloff: 0 @@ -89,6 +89,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: bd020e551a441b14da4e1491aa555bac, type: 3} m_Name: m_EditorClassIdentifier: + _instanceID: 46272 --- !u!33 &4392546155774236836 MeshFilter: m_ObjectHideFlags: 0 @@ -97,16 +98,3 @@ MeshFilter: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 5446999501863086646} m_Mesh: {fileID: 0} ---- !u!114 &171621741425913877 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5446999501863086646} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Spinner (Builtin).prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Spinner (Builtin).prefab index 231bf36bb..3ecf933f9 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Spinner (Builtin).prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Spinner (Builtin).prefab @@ -29,6 +29,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1544373133874741422} m_RootOrder: 1 @@ -64,6 +65,7 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 @@ -105,7 +107,6 @@ GameObject: - component: {fileID: 1544373133874741422} - component: {fileID: 4041090927828039183} - component: {fileID: -8167358012222226486} - - component: {fileID: 8363762864822562217} m_Layer: 0 m_Name: Spinner (Builtin) m_TagString: Untagged @@ -123,6 +124,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 6219072693502205359} - {fileID: 7410166794513211746} @@ -169,19 +171,6 @@ MonoBehaviour: ShowColliderMesh: 0 ShowAabbs: 0 Elasticity: 0.3 ---- !u!114 &8363762864822562217 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6563151203485904801} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 --- !u!1 &7122666291571779558 GameObject: m_ObjectHideFlags: 0 @@ -210,6 +199,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1544373133874741422} m_RootOrder: 0 @@ -233,6 +223,7 @@ MeshRenderer: m_CastShadows: 1 m_ReceiveShadows: 1 m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 1 m_ReflectionProbeUsage: 1 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Surface.prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Surface.prefab index c38bb28aa..7ae4fbc0c 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Surface.prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Surface.prefab @@ -28,6 +28,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2261584146745169539} m_RootOrder: 1 @@ -44,6 +45,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: ed6ad111d870e3b43a828b6086c08607, type: 3} m_Name: m_EditorClassIdentifier: + _instanceID: 46404 --- !u!33 &6530115296024031604 MeshFilter: m_ObjectHideFlags: 0 @@ -63,7 +65,6 @@ GameObject: - component: {fileID: 2261584146745169539} - component: {fileID: 4363410533903828279} - component: {fileID: 7807490122124131058} - - component: {fileID: -3256406434667294810} m_Layer: 0 m_Name: Surface m_TagString: Untagged @@ -81,6 +82,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: - {fileID: 7705994926884342426} - {fileID: 3323324628286901197} @@ -131,19 +133,6 @@ MonoBehaviour: ElasticityFalloff: 0 Friction: 0.3 Scatter: 0 ---- !u!114 &-3256406434667294810 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4322651706312387308} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 --- !u!1 &8320692886569796201 GameObject: m_ObjectHideFlags: 0 @@ -172,6 +161,7 @@ Transform: m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 2261584146745169539} m_RootOrder: 0 @@ -188,6 +178,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 75abfb7d4ccc1b14bb10b53cb3f60574, type: 3} m_Name: m_EditorClassIdentifier: + _instanceID: 46410 --- !u!33 &6035808683100513115 MeshFilter: m_ObjectHideFlags: 0 diff --git a/VisualPinball.Unity/Assets/Resources/Prefabs/Trigger.prefab b/VisualPinball.Unity/Assets/Resources/Prefabs/Trigger.prefab index 4dd907626..feb6c16e3 100644 --- a/VisualPinball.Unity/Assets/Resources/Prefabs/Trigger.prefab +++ b/VisualPinball.Unity/Assets/Resources/Prefabs/Trigger.prefab @@ -14,7 +14,6 @@ GameObject: - component: {fileID: 3195222361417257232} - component: {fileID: -2367600905824176933} - component: {fileID: 1934921143686933034} - - component: {fileID: -6194213659880748689} m_Layer: 0 m_Name: Trigger m_TagString: Untagged @@ -100,6 +99,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 12ec3c1d7933a674b867fada1788b0f4, type: 3} m_Name: m_EditorClassIdentifier: + _instanceID: 46472 Shape: 0 WireThickness: 0 --- !u!33 &1934921143686933034 @@ -110,16 +110,3 @@ MeshFilter: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 8116499157636777247} m_Mesh: {fileID: 0} ---- !u!114 &-6194213659880748689 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 8116499157636777247} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ea7d7495833204790ba1d3a8755397f8, type: 3} - m_Name: - m_EditorClassIdentifier: - ConversionMode: 1 From a287cb53c8d4e6caacf3fe6885588ec5c87784dc Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 20 Jan 2023 00:37:15 +0100 Subject: [PATCH 021/159] import: Don't unpack prefabs. --- .../VisualPinball.Unity.Editor/Import/VpxPrefab.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxPrefab.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxPrefab.cs index e3f20caf8..6d3730a0a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxPrefab.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxPrefab.cs @@ -45,9 +45,9 @@ public VpxPrefab(Object prefab, TItem item) GameObject = PrefabUtility.InstantiatePrefab(prefab) as GameObject; GameObject!.name = item.Name; _mainComponent = GameObject.GetComponent(); - if (_mainComponent && _mainComponent.HasProceduralMesh) { - PrefabUtility.UnpackPrefabInstance(GameObject, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction); - } + // if (_mainComponent && _mainComponent.HasProceduralMesh) { + // PrefabUtility.UnpackPrefabInstance(GameObject, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction); + // } } public void SetData() From f72bd719eb1312cbbb12a097b94ad6e61ca9688b Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 21 Jan 2023 00:37:35 +0100 Subject: [PATCH 022/159] dots: Don't try to auto-create subscene. --- .../Import/VpxSceneConverter.cs | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs index e6a2083d0..17899b0fc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs @@ -575,9 +575,9 @@ private void CreateRootHierarchy(string tableName = null) } // 1. create table scene - _tableScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive); - _tableScene.name = tableName; - SceneManager.SetActiveScene(_tableScene); + // _tableScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive); + // _tableScene.name = tableName; + // SceneManager.SetActiveScene(_tableScene); // 2. create game object hierarchy _tableGo = new GameObject(tableName); @@ -602,18 +602,20 @@ private void CreateRootHierarchy(string tableName = null) private GameObject MakeSubScene() { - var sceneName = _tableScene.name; - var scenePath = GetScenePath(sceneName); - EditorSceneManager.SaveScene(_tableScene, scenePath); - EditorSceneManager.CloseScene(_tableScene, true); - - // link table scene as sub scene - var subSceneGo = new GameObject(sceneName); - var subSceneMb = subSceneGo.AddComponent(); - var subSceneAsset = AssetDatabase.LoadAssetAtPath(scenePath); - subSceneMb.SceneAsset = subSceneAsset; - - return subSceneGo; + // var sceneName = _tableScene.name; + // var scenePath = GetScenePath(sceneName); + // EditorSceneManager.SaveScene(_tableScene, scenePath); + // EditorSceneManager.CloseScene(_tableScene, true); + // + // // link table scene as sub scene + // var subSceneGo = new GameObject(sceneName); + // var subSceneMb = subSceneGo.AddComponent(); + // var subSceneAsset = AssetDatabase.LoadAssetAtPath(scenePath); + // subSceneMb.SceneAsset = subSceneAsset; + // + // return subSceneGo; + + return _tableGo; } private static string GetScenePath(string tableName) From 7ac2335a3e09a9a2cb24d934e5c713a3f4f075a4 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Jan 2023 00:38:48 +0100 Subject: [PATCH 023/159] dots: Don't add component when baking flipper. --- .../VPT/Flipper/FlipperBaker.cs | 103 +++++++++--------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs index 09151ad5e..a93267931 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs @@ -58,68 +58,69 @@ private void SetupFlipperCorrection(FlipperComponent authoring, Player player, F { var fc = colliderComponent.FlipperCorrection; - // create trigger - var triggerData = CreateCorrectionTriggerData(authoring); - var triggerEntity = CreateAdditionalEntity(); - AddComponent(triggerEntity, new TriggerStaticData()); - player.RegisterTrigger(triggerData, triggerEntity, authoring.gameObject); - - using (var builder = new BlobBuilder(Allocator.Temp)) { - - ref var root = ref builder.ConstructRoot(); - root.FlipperEntity = GetEntity(); - root.TimeDelayMs = fc.TimeThresholdMs; - - // Discretize the curves - var polarities = builder.Allocate(ref root.Polarities, fc.PolaritiesCurveSlicingCount + 1); - if (fc.Polarities != null) + // create trigger + var triggerData = CreateCorrectionTriggerData(authoring); + var triggerEntity = CreateAdditionalEntity(); + AddComponent(triggerEntity, new TriggerStaticData()); + // todo add proper colliders + //player.RegisterTrigger(triggerData, triggerEntity, authoring.gameObject); + + using (var builder = new BlobBuilder(Allocator.Temp)) { + + ref var root = ref builder.ConstructRoot(); + root.FlipperEntity = GetEntity(); + root.TimeDelayMs = fc.TimeThresholdMs; + + // Discretize the curves + var polarities = builder.Allocate(ref root.Polarities, fc.PolaritiesCurveSlicingCount + 1); + if (fc.Polarities != null) + { + var curve = fc.Polarities; + float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.PolaritiesCurveSlicingCount; + int i = 0; + for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) { - var curve = fc.Polarities; - float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.PolaritiesCurveSlicingCount; - int i = 0; - for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) - { - polarities[i].x = t; - polarities[i++].y = curve.Evaluate(t); - } + polarities[i].x = t; + polarities[i++].y = curve.Evaluate(t); } - else + } + else + { + for (int i = 0; i < fc.PolaritiesCurveSlicingCount + 1; i++) { - for (int i = 0; i < fc.PolaritiesCurveSlicingCount + 1; i++) - { - polarities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; - polarities[i].y = 0F; - } + polarities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; + polarities[i].y = 0F; } + } - var velocities = builder.Allocate(ref root.Velocities, fc.VelocitiesCurveSlicingCount + 1); - if (fc.Velocities != null) + var velocities = builder.Allocate(ref root.Velocities, fc.VelocitiesCurveSlicingCount + 1); + if (fc.Velocities != null) + { + var curve = fc.Velocities; + float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.VelocitiesCurveSlicingCount; + int i = 0; + for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) { - var curve = fc.Velocities; - float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.VelocitiesCurveSlicingCount; - int i = 0; - for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) - { - velocities[i].x = t; - velocities[i++].y = curve.Evaluate(t); - } + velocities[i].x = t; + velocities[i++].y = curve.Evaluate(t); } - else + } + else + { + for (int i = 0; i < fc.VelocitiesCurveSlicingCount + 1; i++) { - for (int i = 0; i < fc.VelocitiesCurveSlicingCount + 1; i++) - { - velocities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; - velocities[i].y = 1F; - } + velocities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; + velocities[i].y = 1F; } + } - var blobAssetRef = builder.CreateBlobAssetReference(Allocator.Persistent); + var blobAssetRef = builder.CreateBlobAssetReference(Allocator.Persistent); - // add correction data - AddComponent(triggerEntity, new FlipperCorrectionData { - Value = blobAssetRef - }); - } + // add correction data + AddComponent(triggerEntity, new FlipperCorrectionData { + Value = blobAssetRef + }); + } } public TriggerData CreateCorrectionTriggerData(FlipperComponent authoring) From 176e3651d97b9d91f5599050c69d85e4e4170780 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 23 Jan 2023 22:36:33 +0100 Subject: [PATCH 024/159] dots: Disable all systems. --- .../Materials/Dot Matrix Display (SRP).mat | 11 ++++-- .../Materials/Segment Display (SRP).mat | 11 ++++-- .../Game/InitPlayerSystem.cs | 30 ++++++++++++++ .../Game/InitPlayerSystem.cs.meta | 3 ++ .../Game/SystemBaseStub.cs | 37 ++++++++++++++++++ .../Game/SystemBaseStub.cs.meta | 3 ++ .../VisualPinballSimulationSystemGroup.cs | 6 ++- .../Physics/Collision/ContactSystem.cs | 3 +- .../Collision/DynamicBroadPhaseSystem.cs | 3 +- .../Collision/DynamicCollisionSystem.cs | 3 +- .../Collision/DynamicNarrowPhaseSystem.cs | 3 +- .../Collision/StaticBroadPhaseSystem.cs | 3 +- .../Collision/StaticCollisionSystem.cs | 3 +- .../Collision/StaticNarrowPhaseSystem.cs | 3 +- .../SystemGroup/SimulateBuildSystem.cs | 3 +- .../SystemGroup/SimulateCycleSystemGroup.cs | 39 ++++++++++--------- .../VPT/Ball/BallDisplacementSystem.cs | 3 +- .../VPT/Ball/BallMovementSystem.cs | 3 +- .../VPT/Ball/BallRingCounterSystem.cs | 3 +- .../VPT/Ball/BallSpinHackSystem.cs | 3 +- .../VPT/Ball/BallVelocitySystem.cs | 3 +- .../VPT/Bumper/BumperRingAnimationSystem.cs | 3 +- .../VPT/Bumper/BumperRingMovementSystem.cs | 3 +- .../VPT/Bumper/BumperSkirtAnimationSystem.cs | 3 +- .../VPT/Bumper/BumperSkirtMovementSystem.cs | 3 +- .../VPT/Flipper/FlipperBaker.cs | 8 +++- .../VPT/Flipper/FlipperDisplacementSystem.cs | 3 +- .../VPT/Flipper/FlipperRotateSystem.cs | 3 +- .../VPT/Flipper/FlipperVelocitySystem.cs | 3 +- .../VPT/Gate/GateDisplacementSystem.cs | 3 +- .../VPT/Gate/GateMovementSystem.cs | 3 +- .../VPT/Gate/GateVelocitySystem.cs | 3 +- .../HitTarget/DropTargetAnimationSystem.cs | 3 +- .../DropTargetTransformationSystem.cs | 3 +- .../VPT/HitTarget/HitTargetAnimationSystem.cs | 3 +- .../HitTargetTransformationSystem.cs | 3 +- .../VPT/Playfield/PlayfieldComponent.cs | 3 +- .../VPT/Plunger/PlungerAnimationSystem.cs | 3 +- .../VPT/Plunger/PlungerDisplacementSystem.cs | 3 +- .../Plunger/PlungerTransformationSystem.cs | 3 +- .../VPT/Plunger/PlungerVelocitySystem.cs | 3 +- .../VPT/Spinner/SpinnerDisplacementSystem.cs | 3 +- .../VPT/Spinner/SpinnerMovementSystem.cs | 3 +- .../VPT/Spinner/SpinnerVelocitySystem.cs | 3 +- .../VPT/Trigger/TriggerAnimationSystem.cs | 3 +- .../VPT/Trigger/TriggerMovementSystem.cs | 3 +- 46 files changed, 194 insertions(+), 65 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs.meta diff --git a/VisualPinball.Unity/Assets/Resources/Materials/Dot Matrix Display (SRP).mat b/VisualPinball.Unity/Assets/Resources/Materials/Dot Matrix Display (SRP).mat index b5de4b958..efb2476c7 100644 --- a/VisualPinball.Unity/Assets/Resources/Materials/Dot Matrix Display (SRP).mat +++ b/VisualPinball.Unity/Assets/Resources/Materials/Dot Matrix Display (SRP).mat @@ -12,13 +12,13 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: da692e001514ec24dbc4cca1949ff7e8, type: 3} m_Name: m_EditorClassIdentifier: - version: 12 + version: 13 hdPluginSubTargetMaterialVersions: m_Keys: [] m_Values: --- !u!21 &2100000 Material: - serializedVersion: 6 + serializedVersion: 8 m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} @@ -26,7 +26,11 @@ Material: m_Name: Dot Matrix Display (SRP) m_Shader: {fileID: -6465566751694194690, guid: 3dfbd2115636a284d89d71fdefd9b4d2, type: 3} - m_ShaderKeywords: _DISABLE_SSR_TRANSPARENT + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_InvalidKeywords: [] m_LightmapFlags: 4 m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 @@ -39,6 +43,7 @@ Material: - TransparentBackface - RayTracingPrepass - MOTIONVECTORS + m_LockedProperties: m_SavedProperties: serializedVersion: 3 m_TexEnvs: diff --git a/VisualPinball.Unity/Assets/Resources/Materials/Segment Display (SRP).mat b/VisualPinball.Unity/Assets/Resources/Materials/Segment Display (SRP).mat index 2f6b33f62..923011b22 100644 --- a/VisualPinball.Unity/Assets/Resources/Materials/Segment Display (SRP).mat +++ b/VisualPinball.Unity/Assets/Resources/Materials/Segment Display (SRP).mat @@ -12,13 +12,13 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: da692e001514ec24dbc4cca1949ff7e8, type: 3} m_Name: m_EditorClassIdentifier: - version: 12 + version: 13 hdPluginSubTargetMaterialVersions: m_Keys: [] m_Values: --- !u!21 &2100000 Material: - serializedVersion: 6 + serializedVersion: 8 m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} @@ -26,7 +26,11 @@ Material: m_Name: Segment Display (SRP) m_Shader: {fileID: -6465566751694194690, guid: d54eb986991300e419411008eb1f597d, type: 3} - m_ShaderKeywords: _DISABLE_SSR_TRANSPARENT + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: + - _DISABLE_SSR_TRANSPARENT + m_InvalidKeywords: [] m_LightmapFlags: 4 m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 @@ -39,6 +43,7 @@ Material: - TransparentBackface - RayTracingPrepass - MOTIONVECTORS + m_LockedProperties: m_SavedProperties: serializedVersion: 3 m_TexEnvs: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs new file mode 100644 index 000000000..c2e9da3dc --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs @@ -0,0 +1,30 @@ +using Unity.Entities; +using UnityEngine; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + [UpdateInGroup(typeof(InitializationSystemGroup))] + internal partial class InitPlayerSystem : SystemBase + { + protected override void OnCreate() + { + base.OnCreate(); + Debug.Log($"[INIT] Created."); + + Debug.Log($"[INIT] Initializing GameObjects..."); + Entities.WithoutBurst().ForEach((Entity entity, in FlipperBaker.GameObjectContainer goc) => + { + + //var tf = EntityManager.GetComponentObject(entity); + Debug.Log($"[INIT] Initializing GameObject {goc.GameObject.name}..."); + + }).Run(); + } + + protected override void OnUpdate() + { + + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs.meta new file mode 100644 index 000000000..32f84601c --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6a579458cc094d218bcdf855bdcf4529 +timeCreated: 1675253461 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs new file mode 100644 index 000000000..58a8779c3 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs @@ -0,0 +1,37 @@ +using Unity.Entities; +using Unity.Entities.CodeGeneratedJobForEach; + +namespace VisualPinball.Unity.VisualPinball.Unity.Game +{ + public abstract class SystemBaseStub + { + protected abstract void OnUpdate(); + protected virtual void OnCreate() { } + protected virtual void OnStartRunning() { } + protected virtual void OnDestroy() { } + + public void Update() { } + + public ComponentLookup GetComponentLookup(bool isReadOnly = false) where T : unmanaged, IComponentData => default; + + public T GetComponentData(Entity entity) where T : unmanaged, IComponentData => default; + + public EntityManager EntityManager => default; + + public World World => default; + + protected internal LambdaSingleJobDescription Job => new LambdaSingleJobDescription(); + + protected internal T GetComponent(Entity entity) where T : unmanaged, IComponentData => EntityManager.GetComponentData(entity); + + protected internal void SetComponent(Entity entity, T component) where T : unmanaged, IComponentData => EntityManager.SetComponentData(entity, component); + + protected internal bool HasComponent(Entity entity) where T : unmanaged, IComponentData => false; + + protected internal EntityQuery GetEntityQuery(params ComponentType[] componentTypes) => default; + + protected internal ForEachLambdaJobDescription Entities => new ForEachLambdaJobDescription(); + + public new BufferLookup GetBufferLookup(bool isReadOnly = false) where T : unmanaged, IBufferElementData => default; + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs.meta new file mode 100644 index 000000000..5d73a3ae2 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c49f3b7a47af43d68216e6545ed8c13b +timeCreated: 1675516205 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs index eab87a883..5fe90e0a5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs @@ -64,14 +64,16 @@ protected override void OnCreate() _createBallEntityCommandBufferSystem = World.GetOrCreateSystemManaged(); _velocitiesSystemGroup = World.GetOrCreateSystemManaged(); _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - _ballRingCounterSystem = World.GetOrCreateSystemManaged(); + // todo re-enable system + // _ballRingCounterSystem = World.GetOrCreateSystemManaged(); _updateAnimationsSystemGroup = World.GetOrCreateSystemManaged(); _transformMeshesSystemGroup = World.GetOrCreateSystemManaged(); _systemsToUpdate.Add(_createBallEntityCommandBufferSystem); _systemsToUpdate.Add(_velocitiesSystemGroup); _systemsToUpdate.Add(_simulateCycleSystemGroup); - _systemsToUpdate.Add(_ballRingCounterSystem); + // todo re-enable system + // _systemsToUpdate.Add(_ballRingCounterSystem); _systemsToUpdate.Add(_updateAnimationsSystemGroup); _systemsToUpdate.Add(_transformMeshesSystemGroup); base.OnCreate(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs index 60ef53ad3..6655bbce4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs @@ -21,12 +21,13 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; using Collider = UnityEngine.Collider; namespace VisualPinballUnity { [DisableAutoCreation] - internal partial class ContactSystem : SystemBase + internal partial class ContactSystem : SystemBaseStub { private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs index 11ed95ca9..3977ad3d3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs @@ -18,11 +18,12 @@ using Unity.Entities; using Unity.Profiling; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [DisableAutoCreation] - internal partial class DynamicBroadPhaseSystem : SystemBase + internal partial class DynamicBroadPhaseSystem : SystemBaseStub { private EntityQuery _ballQuery; private static readonly ProfilerMarker PerfMarker1 = new ProfilerMarker("DynamicBroadPhaseSystem.CreateKdTree"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs index cc881d6a2..d25fe1f2b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs @@ -17,11 +17,12 @@ using Unity.Entities; using Unity.Profiling; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [DisableAutoCreation] - internal partial class DynamicCollisionSystem : SystemBase + internal partial class DynamicCollisionSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("DynamicCollisionSystem"); private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs index d3ed59bf9..d1731c915 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs @@ -17,11 +17,12 @@ using Unity.Entities; using Unity.Profiling; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [DisableAutoCreation] - internal partial class DynamicNarrowPhaseSystem : SystemBase + internal partial class DynamicNarrowPhaseSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("DynamicNarrowPhaseSystem"); private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs index b2ecfa2fd..72b34809e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs @@ -17,11 +17,12 @@ using Unity.Entities; using Unity.Profiling; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [DisableAutoCreation] - internal partial class StaticBroadPhaseSystem : SystemBase + internal partial class StaticBroadPhaseSystem : SystemBaseStub { private EntityQuery _quadTreeEntityQuery; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs index e961253e1..39f798453 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs @@ -22,13 +22,14 @@ using Unity.Profiling; using VisualPinball.Engine.VPT; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; using Object = UnityEngine.Object; using Random = UnityEngine.Random; namespace VisualPinballUnity { [DisableAutoCreation] - internal partial class StaticCollisionSystem : SystemBase + internal partial class StaticCollisionSystem : SystemBaseStub { private Player _player; private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs index 7b2af9c1c..573bfa4d4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs @@ -20,11 +20,12 @@ using Unity.Profiling; using VisualPinball.Engine.VPT; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [DisableAutoCreation] - internal partial class StaticNarrowPhaseSystem : SystemBase + internal partial class StaticNarrowPhaseSystem : SystemBaseStub { public bool CollideAgainstPlayfieldPlane; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs index 8cf457fbc..1f3818c13 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs @@ -19,11 +19,12 @@ using Unity.Transforms; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateBefore(typeof(TransformMeshesSystemGroup))] - internal partial class SimulateBuildSystem : SystemBase + internal partial class SimulateBuildSystem : SystemBaseStub { private float4x4 _baseTransform; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs index e4f6759b6..1aa466302 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs @@ -77,25 +77,26 @@ protected override void OnCreate() _flipperDataQuery = EntityManager.CreateEntityQuery(ComponentType.ReadOnly(), ComponentType.ReadOnly()); _collisionEventDataQuery = EntityManager.CreateEntityQuery(ComponentType.ReadOnly()); - _simulationSystemGroup = World.GetExistingSystemManaged(); - _staticBroadPhaseSystem = World.GetExistingSystemManaged(); - _dynamicBroadPhaseSystem = World.GetExistingSystemManaged(); - _staticNarrowPhaseSystem = World.GetExistingSystemManaged(); - _dynamicNarrowPhaseSystem = World.GetExistingSystemManaged(); - _displacementSystemGroup = World.GetExistingSystemManaged(); - _staticCollisionSystem = World.GetExistingSystemManaged(); - _dynamicCollisionSystem = World.GetExistingSystemManaged(); - _contactSystem = World.GetExistingSystemManaged(); - _ballSpinHackSystem = World.GetExistingSystemManaged(); - _systemsToUpdate.Add(_staticBroadPhaseSystem); - _systemsToUpdate.Add(_dynamicBroadPhaseSystem); - _systemsToUpdate.Add(_staticNarrowPhaseSystem); - _systemsToUpdate.Add(_dynamicNarrowPhaseSystem); - _systemsToUpdate.Add(_displacementSystemGroup); - _systemsToUpdate.Add(_staticCollisionSystem); - _systemsToUpdate.Add(_dynamicCollisionSystem); - _systemsToUpdate.Add(_contactSystem); - _systemsToUpdate.Add(_ballSpinHackSystem); + // todo re-enable systems + // _simulationSystemGroup = World.GetExistingSystemManaged(); + // _staticBroadPhaseSystem = World.GetExistingSystemManaged(); + // _dynamicBroadPhaseSystem = World.GetExistingSystemManaged(); + // _staticNarrowPhaseSystem = World.GetExistingSystemManaged(); + // _dynamicNarrowPhaseSystem = World.GetExistingSystemManaged(); + // _displacementSystemGroup = World.GetExistingSystemManaged(); + // _staticCollisionSystem = World.GetExistingSystemManaged(); + // _dynamicCollisionSystem = World.GetExistingSystemManaged(); + // _contactSystem = World.GetExistingSystemManaged(); + // _ballSpinHackSystem = World.GetExistingSystemManaged(); + // _systemsToUpdate.Add(_staticBroadPhaseSystem); + // _systemsToUpdate.Add(_dynamicBroadPhaseSystem); + // _systemsToUpdate.Add(_staticNarrowPhaseSystem); + // _systemsToUpdate.Add(_dynamicNarrowPhaseSystem); + // _systemsToUpdate.Add(_displacementSystemGroup); + // _systemsToUpdate.Add(_staticCollisionSystem); + // _systemsToUpdate.Add(_dynamicCollisionSystem); + // _systemsToUpdate.Add(_contactSystem); + // _systemsToUpdate.Add(_ballSpinHackSystem); Contacts = new NativeList(Allocator.Persistent); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs index d87220570..fcb1126f7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs @@ -19,11 +19,12 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal partial class BallDisplacementSystem : SystemBase + internal partial class BallDisplacementSystem : SystemBaseStub { private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs index 0c69b5bf7..a90541859 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs @@ -19,13 +19,14 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; using Physics = UnityEngine.Physics; namespace VisualPinballUnity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class BallMovementSystem : SystemBase + internal partial class BallMovementSystem : SystemBaseStub { private float4x4 _baseTransform; private Player _player; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs index 0bc767d65..732c28a48 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs @@ -17,11 +17,12 @@ using Unity.Entities; using VisualPinball.Engine.Common; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [DisableAutoCreation] - internal partial class BallRingCounterSystem : SystemBase + internal partial class BallRingCounterSystem : SystemBaseStub { public const int MaxBallTrailPos = 10; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs index 98dda1527..f04a49b4b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs @@ -18,11 +18,12 @@ using Unity.Mathematics; using VisualPinball.Engine.Common; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [DisableAutoCreation] - internal partial class BallSpinHackSystem : SystemBase + internal partial class BallSpinHackSystem : SystemBaseStub { protected override void OnUpdate() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs index 001d1aee5..c6110c7b0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs @@ -22,11 +22,12 @@ using UnityEngine; using VisualPinball.Engine.Common; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal partial class BallVelocitySystem : SystemBase + internal partial class BallVelocitySystem : SystemBaseStub { private float3 _gravity; private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallVelocitySystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs index cf61b9e62..f3695f7b8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs @@ -17,11 +17,12 @@ using Unity.Entities; using Unity.Profiling; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class BumperRingAnimationSystem : SystemBase + internal partial class BumperRingAnimationSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperRingAnimationSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs index 24578f57a..41d47fc80 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs @@ -19,12 +19,13 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; using Physics = UnityEngine.Physics; namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class BumperRingMovementSystem : SystemBase + internal partial class BumperRingMovementSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperRingMovementSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs index 6dcacc3a9..45731c7d0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs @@ -18,11 +18,12 @@ using Unity.Mathematics; using Unity.Profiling; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class BumperSkirtAnimationSystem : SystemBase + internal partial class BumperSkirtAnimationSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperSkirtAnimationSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs index 33383090f..b68e5a926 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs @@ -19,11 +19,12 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class BumperSkirtMovementSystem : SystemBase + internal partial class BumperSkirtMovementSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperSkirtMovementSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs index a93267931..afc8ac698 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs @@ -17,6 +17,7 @@ using System; using Unity.Collections; using Unity.Entities; +using UnityEngine; using VisualPinball.Engine.Math; using VisualPinball.Engine.VPT.Flipper; using VisualPinball.Engine.VPT.Trigger; @@ -43,6 +44,7 @@ public override void Bake(FlipperComponent authoring) AddComponent(authoring.GetHitData()); AddComponent(authoring.GetFlipperTricksData(colliderComponent, d)); AddComponent(new SolenoidStateData { Value = false }); + AddComponentObject(new GameObjectContainer { GameObject = authoring.gameObject }); // flipper correction (nFozzy) if (colliderComponent.FlipperCorrection) { @@ -145,6 +147,10 @@ public TriggerData CreateCorrectionTriggerData(FlipperComponent authoring) } throw new InvalidOperationException("Cannot create correction trigger for flipper outside of the table hierarchy."); } - + + internal class GameObjectContainer : IComponentData + { + public GameObject GameObject; + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs index eeb617728..0dd3abe7d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs @@ -21,12 +21,13 @@ using UnityEngine; using VisualPinball.Engine.Game; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal partial class FlipperDisplacementSystem : SystemBase + internal partial class FlipperDisplacementSystem : SystemBaseStub { private Player _player; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs index 3a1b6d1c3..bc2926502 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs @@ -19,12 +19,13 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class FlipperRotateSystem : SystemBase + internal partial class FlipperRotateSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("FlipperRotateSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs index e2b76aeff..250d999e8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs @@ -21,12 +21,13 @@ using Unity.Profiling; using VisualPinball.Engine.Common; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal partial class FlipperVelocitySystem : SystemBase + internal partial class FlipperVelocitySystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("FlipperVelocitySystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs index f50d4812e..fe96e4822 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs @@ -21,11 +21,12 @@ using UnityEngine; using VisualPinball.Engine.Game; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal partial class GateDisplacementSystem : SystemBase + internal partial class GateDisplacementSystem : SystemBaseStub { private Player _player; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs index 7466eadc4..4795bc1d9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs @@ -19,11 +19,12 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class GateMovementSystem : SystemBase + internal partial class GateMovementSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("GateMovementSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs index f39cb59b6..98660361c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs @@ -21,11 +21,12 @@ using Unity.Profiling; using VisualPinball.Engine.Common; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal partial class GateVelocitySystem : SystemBase + internal partial class GateVelocitySystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("GateVelocitySystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs index e3cd4939f..a5996fe24 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs @@ -20,11 +20,12 @@ using UnityEngine; using VisualPinball.Engine.Game; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class DropTargetAnimationSystem : SystemBase + internal partial class DropTargetAnimationSystem : SystemBaseStub { private Player _player; private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs index 01de9cf8d..27b018a18 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs @@ -18,12 +18,13 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; using Physics = UnityEngine.Physics; namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class DropTargetTransformationSystem : SystemBase + internal partial class DropTargetTransformationSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker(nameof(DropTargetTransformationSystem)); private Player _player; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs index e53643af6..fca5b0d35 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs @@ -18,11 +18,12 @@ using Unity.Entities; using Unity.Profiling; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class HitTargetAnimationSystem : SystemBase + internal partial class HitTargetAnimationSystem : SystemBaseStub { private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; private NativeQueue _eventQueue; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs index 119b585c3..73c67437e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs @@ -18,11 +18,12 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class HitTargetTransformationSystem : SystemBase + internal partial class HitTargetTransformationSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker(nameof(HitTargetTransformationSystem)); private Player _player; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs index 0c91e51e5..3a1a208f8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs @@ -108,7 +108,8 @@ private void Awake() GetComponentInParent().RegisterPlayfield(gameObject); var meshComp = GetComponentInChildren(); if (meshComp) { - World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged().CollideAgainstPlayfieldPlane = meshComp.AutoGenerate; + // todo re-enable system + // World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged().CollideAgainstPlayfieldPlane = meshComp.AutoGenerate; } transform.RotateAround(Vector3.zero, Vector3.right, -RenderSlope); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs index 8d510e8ef..716505140 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs @@ -18,11 +18,12 @@ using Unity.Mathematics; using Unity.Profiling; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class PlungerAnimationSystem : SystemBase + internal partial class PlungerAnimationSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("PlungerAnimationSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs index 1b78f020e..cd7399b4b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs @@ -21,11 +21,12 @@ using UnityEngine; using VisualPinball.Engine.Game; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal partial class PlungerDisplacementSystem : SystemBase + internal partial class PlungerDisplacementSystem : SystemBaseStub { private Player _player; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs index beb21ce0c..7fd8a4974 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs @@ -18,11 +18,12 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class PlungerTransformationSystem : SystemBase + internal partial class PlungerTransformationSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("PlungerTransformationSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs index 559a5900c..c561c4991 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs @@ -17,11 +17,12 @@ using Unity.Entities; using Unity.Profiling; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal partial class PlungerVelocitySystem : SystemBase + internal partial class PlungerVelocitySystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("PlungerVelocitySystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs index 1048f7a11..9095c59ee 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs @@ -23,11 +23,12 @@ using UnityEngine; using VisualPinball.Engine.Game; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal partial class SpinnerDisplacementSystem : SystemBase + internal partial class SpinnerDisplacementSystem : SystemBaseStub { private Player _player; private SimulateCycleSystemGroup _simulateCycleSystemGroup; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs index 490602992..41f5a8f4f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs @@ -19,11 +19,12 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class SpinnerMovementSystem : SystemBase + internal partial class SpinnerMovementSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("SpinnerMovementSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs index 76b1bd012..1d2e660c2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs @@ -19,11 +19,12 @@ using Unity.Profiling; using VisualPinball.Engine.Common; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal partial class SpinnerVelocitySystem : SystemBase + internal partial class SpinnerVelocitySystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("SpinnerVelocitySystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs index 1ee0be4e6..04db3171c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs @@ -18,11 +18,12 @@ using Unity.Profiling; using VisualPinball.Engine.VPT; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class TriggerAnimationSystem : SystemBase + internal partial class TriggerAnimationSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("TriggerAnimationSystem"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs index 8643e2039..436ad0e08 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs @@ -19,12 +19,13 @@ using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; using Physics = UnityEngine.Physics; namespace VisualPinballUnity { [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class TriggerMovementSystem : SystemBase + internal partial class TriggerMovementSystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("TriggerMovementSystem"); From 883bb70ce2707a639e1d9c3b540829589f23429f Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 24 Jan 2023 22:47:19 +0100 Subject: [PATCH 025/159] fix: Confused imports. --- .../VisualPinball.Unity.Patcher/Matcher/TablePatcher.cs | 6 +++--- VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Patcher/Matcher/TablePatcher.cs b/VisualPinball.Unity/VisualPinball.Unity.Patcher/Matcher/TablePatcher.cs index 56d6183a4..c3f00d545 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Patcher/Matcher/TablePatcher.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Patcher/Matcher/TablePatcher.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using System; -using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; @@ -26,6 +25,7 @@ using VisualPinball.Unity.Editor; using Light = UnityEngine.Light; using Object = UnityEngine.Object; +using VpeLight = VisualPinball.Engine.VPT.Light.Light; namespace VisualPinball.Unity.Patcher { @@ -373,7 +373,7 @@ protected static void LightPos(GameObject go, float x, float y, float z) /// protected static LightComponent CreateLight(string name, float x, float y, GameObject parentGo) { - var light = Engine.VPT.Light.Light.GetDefault(name, x, y); + var light = VpeLight.GetDefault(name, x, y); light.Data.ShowBulbMesh = false; var prefab = RenderPipeline.Current.PrefabProvider.CreateLight(); @@ -401,7 +401,7 @@ protected GameObject ConvertToInsertLight(LightComponent lo) var name = lo.name; var parent = lo.transform.parent.gameObject; Object.DestroyImmediate(lo.gameObject); - return CreateInsertLight(TableContainer.Get(name).Data, parent); + return CreateInsertLight(TableContainer.Get(name).Data, parent); } /// diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 6b93b262d..169352359 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -28,6 +28,7 @@ using VisualPinball.Engine.VPT.Trigger; using VisualPinballUnity; using Logger = NLog.Logger; +using Color = VisualPinball.Engine.Math.Color; namespace VisualPinball.Unity { @@ -122,7 +123,7 @@ public class Player : MonoBehaviour public void SetLamp(string lampId, float value) => _lampPlayer.HandleLampEvent(lampId, value); public void SetLamp(string lampId, LampStatus status) => _lampPlayer.HandleLampEvent(lampId, status); - public void SetLamp(string lampId, VisualPinball.Engine.Math.Color color) => _lampPlayer.HandleLampEvent(lampId, color); + public void SetLamp(string lampId, Color color) => _lampPlayer.HandleLampEvent(lampId, color); #endregion From 565ba31d200e084c3156f0c1df3a686214829acd Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 25 Jan 2023 00:05:50 +0100 Subject: [PATCH 026/159] dots: Fix camera orbit when in different scene. --- .../VisualPinball.Unity/Game/CameraTranslateAndOrbit.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/CameraTranslateAndOrbit.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/CameraTranslateAndOrbit.cs index f59d8b3c3..0da2e2d91 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/CameraTranslateAndOrbit.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/CameraTranslateAndOrbit.cs @@ -51,12 +51,11 @@ private void Start() { var playfield = FindObjectOfType(); - var pfr = playfield.GetComponent(); - if (pfr) { + var pfr = playfield == null ? null : playfield.GetComponent(); + if (pfr != null) { positionOffset = pfr.bounds.center; } - _radius = Vector3.Distance(Vector3.zero, transform.position); transformCache = transform; _focusPoint = transformCache.forward * -1f * _radius; From 6feda4672201cc30a83670ad04e96021813846c5 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 26 Jan 2023 00:06:11 +0100 Subject: [PATCH 027/159] dots: Remove disposal --- .../Physics/SystemGroup/SimulateCycleSystemGroup.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs index 1aa466302..9a6a08a4b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs @@ -103,8 +103,8 @@ protected override void OnCreate() protected override void OnDestroy() { - Contacts.Dispose(); - ItemsColliding.Dispose(); + // Contacts.Dispose(); + // ItemsColliding.Dispose(); } protected override void OnUpdate() From c7bebd2fec15156a720e951a168cb6d032446e19 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 27 Jan 2023 00:06:43 +0100 Subject: [PATCH 028/159] dots: Temporarily disable DOTS in physics engine. --- .../Physics/Engine/DefaultPhysicsEngine.cs | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs index a5f3e7a95..a654380da 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs @@ -32,8 +32,8 @@ public class DefaultPhysicsEngine : IPhysicsEngine public BallManager _ballManager; private EntityManager _entityManager; - private EntityQuery _flipperDataQuery; - private EntityQuery _ballDataQuery; + // private EntityQuery _flipperDataQuery; + // private EntityQuery _ballDataQuery; private Matrix4x4 _worldToLocal; private DebugFlipperState[] _flipperStates = new DebugFlipperState[0]; @@ -46,13 +46,13 @@ public void Init(TableComponent tableComponent, BallManager ballManager) { _ballManager = ballManager; _entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - _flipperDataQuery = _entityManager.CreateEntityQuery( - ComponentType.ReadOnly(), - ComponentType.ReadOnly(), - ComponentType.ReadOnly() - ); - - _ballDataQuery = _entityManager.CreateEntityQuery(ComponentType.ReadOnly()); + // _flipperDataQuery = _entityManager.CreateEntityQuery( + // ComponentType.ReadOnly(), + // ComponentType.ReadOnly(), + // ComponentType.ReadOnly() + // ); + // + // _ballDataQuery = _entityManager.CreateEntityQuery(ComponentType.ReadOnly()); _visualPinballSimulationSystemGroup = _entityManager.World.GetOrCreateSystemManaged(); var simulateCycleSystemGroup = _entityManager.World.GetOrCreateSystemManaged(); @@ -136,23 +136,23 @@ public float GetFlipperDebugValue(DebugFlipperSliderParam param) public void UpdateDebugFlipperStates() { - // for each flipper - var entities = _flipperDataQuery.ToEntityArray(Allocator.TempJob); - if (_flipperStates.Length == 0) { - _flipperStates = new DebugFlipperState[entities.Length]; - } - for (var i = 0; i < entities.Length; i++) { - var entity = entities[i]; - var movementData = _entityManager.GetComponentData(entity); - var staticData = _entityManager.GetComponentData(entity); - var solenoidData = _entityManager.GetComponentData(entity); - _flipperStates[i] = new DebugFlipperState( - entity, - math.degrees(math.abs(movementData.Angle - staticData.AngleStart)), - solenoidData.Value - ); - } - entities.Dispose(); + // // for each flipper + // var entities = _flipperDataQuery.ToEntityArray(Allocator.TempJob); + // if (_flipperStates.Length == 0) { + // _flipperStates = new DebugFlipperState[entities.Length]; + // } + // for (var i = 0; i < entities.Length; i++) { + // var entity = entities[i]; + // var movementData = _entityManager.GetComponentData(entity); + // var staticData = _entityManager.GetComponentData(entity); + // var solenoidData = _entityManager.GetComponentData(entity); + // _flipperStates[i] = new DebugFlipperState( + // entity, + // math.degrees(math.abs(movementData.Angle - staticData.AngleStart)), + // solenoidData.Value + // ); + // } + // entities.Dispose(); } public void PushPendingCreateBallNotifications() @@ -160,21 +160,21 @@ public void PushPendingCreateBallNotifications() if (_nextBallIdToNotifyDebugUI == _ballManager.NumBallsCreated) return; // nothing to report - var entities = _ballDataQuery.ToEntityArray(Allocator.TempJob); - int numBallsToReport = _ballManager.NumBallsCreated - _nextBallIdToNotifyDebugUI; - foreach (var entity in entities) - { - var ballData = _entityManager.GetComponentData(entity); - if (ballData.Id >= _nextBallIdToNotifyDebugUI) - { - EngineProvider.Get().OnCreateBall(entity); - --numBallsToReport; - } - } - - // error checking - Assert.AreEqual(0, numBallsToReport); - _nextBallIdToNotifyDebugUI = _ballManager.NumBallsCreated; + // var entities = _ballDataQuery.ToEntityArray(Allocator.TempJob); + // int numBallsToReport = _ballManager.NumBallsCreated - _nextBallIdToNotifyDebugUI; + // foreach (var entity in entities) + // { + // var ballData = _entityManager.GetComponentData(entity); + // if (ballData.Id >= _nextBallIdToNotifyDebugUI) + // { + // EngineProvider.Get().OnCreateBall(entity); + // --numBallsToReport; + // } + // } + + // // error checking + // Assert.AreEqual(0, numBallsToReport); + // _nextBallIdToNotifyDebugUI = _ballManager.NumBallsCreated; } } } From 125715c6dd97357a321b513bfbdf4cd63d3e14fb Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 28 Jan 2023 23:59:40 +0100 Subject: [PATCH 029/159] jobs: Create main physics loop. --- .../VisualPinball.Unity/Game/CoilPlayer.cs | 2 +- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 36 ++++++++ .../Game/PhysicsCycle.cs.meta | 3 + .../VisualPinball.Unity/Game/PhysicsEngine.cs | 92 +++++++++++++++++++ .../Game/PhysicsEngine.cs.meta | 3 + .../VisualPinball.Unity/Game/PhysicsStatus.cs | 7 ++ .../Game/PhysicsStatus.cs.meta | 3 + .../VisualPinballSimulationSystemGroup.cs | 70 +++++++------- .../VPT/Kicker/KickerComponent.cs | 2 +- .../VPT/Trough/TroughApi.cs | 2 +- 10 files changed, 182 insertions(+), 38 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/CoilPlayer.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/CoilPlayer.cs index 75fa703f9..d0b5c4316 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/CoilPlayer.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/CoilPlayer.cs @@ -77,7 +77,7 @@ public void OnStart() // check if device exists if (!_coilDevices.ContainsKey(coilMapping.Device)) { - Logger.Error($"Unknown coil device \"{coilMapping.Device.name}\"."); + Logger.Warn($"Unknown coil device \"{coilMapping.Device.name}\"."); break; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs new file mode 100644 index 000000000..beb621db6 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -0,0 +1,36 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using UnityEngine; + +namespace VisualPinball.Unity +{ + public static class PhysicsCycle + { + + public static void Simulate(float dTime) + { + while (dTime > 0) + { + var hitTime = dTime; // begin time search from now ... until delta ends + + Debug.Log("PhysicsCycle.Simulate"); + + dTime -= hitTime; + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs.meta new file mode 100644 index 000000000..7e9bb7946 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 21428d2788334ad59c3394263748202c +timeCreated: 1678661168 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs new file mode 100644 index 000000000..556f264ee --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -0,0 +1,92 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using Unity.Burst; +using Unity.Collections; +using Unity.Jobs; +using UnityEngine; +using VisualPinball.Engine.Common; + +namespace VisualPinball.Unity +{ + public class PhysicsEngine : MonoBehaviour + { + [NonSerialized] + private NativeArray _uSecs; + + private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); + + private void Start() + { + _uSecs = new NativeArray(3, Allocator.Persistent); + _uSecs[0] = NowUsec; // start time + _uSecs[1] = _uSecs[0]; // current time frame + _uSecs[2] = _uSecs[0] + PhysicsConstants.PhysicsStepTime; // next time frame + } + + private void Update() + { + + var updatePhysics = new UpdatePhysicsJob { + InitialTimeUsec = NowUsec, + USecs = _uSecs, + }; + + updatePhysics.Run(); + } + + private void OnDestroy() + { + _uSecs.Dispose(); + } + } + + [BurstCompile] + public struct UpdatePhysicsJob : IJob + { + [ReadOnly] + public ulong InitialTimeUsec; + + public NativeArray USecs; + + public void Execute() + { + var n = 0; + var startTimeUsec = USecs[0]; + var curPhysicsFrameTime = USecs[1]; + var nextPhysicsFrameTime = USecs[2]; + + while (curPhysicsFrameTime < InitialTimeUsec) + { + var timeMsec = (uint)((curPhysicsFrameTime - startTimeUsec) / 1000); + var physicsDiffTime = (float)((nextPhysicsFrameTime - curPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); + + PhysicsCycle.Simulate(physicsDiffTime); + + curPhysicsFrameTime = nextPhysicsFrameTime; + nextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; + + n++; + } + + USecs[1] = curPhysicsFrameTime; + USecs[2] = nextPhysicsFrameTime; + + //Debug.Log($"UpdatePhysic {n}x"); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs.meta new file mode 100644 index 000000000..f79c898f3 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b80d5ee1d3ab4a109515ddcf56026d94 +timeCreated: 1678657655 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs new file mode 100644 index 000000000..03168de3c --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs @@ -0,0 +1,7 @@ +namespace VisualPinball.Unity.VisualPinball.Unity.Game +{ + public struct PhysicsStatus + { + + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs.meta new file mode 100644 index 000000000..3db946934 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b915f496c6ce491ba0ed3143007a1fe8 +timeCreated: 1678661883 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs index 5fe90e0a5..b325b1fb0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs @@ -41,12 +41,12 @@ internal partial class VisualPinballSimulationSystemGroup : ComponentSystemGroup private ulong _nextPhysicsFrameTime; private readonly List _systemsToUpdate = new List(); - private CreateBallEntityCommandBufferSystem _createBallEntityCommandBufferSystem; - private UpdateVelocitiesSystemGroup _velocitiesSystemGroup; - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - private BallRingCounterSystem _ballRingCounterSystem; - private UpdateAnimationsSystemGroup _updateAnimationsSystemGroup; - private TransformMeshesSystemGroup _transformMeshesSystemGroup; + // private CreateBallEntityCommandBufferSystem _createBallEntityCommandBufferSystem; + // private UpdateVelocitiesSystemGroup _velocitiesSystemGroup; + // private SimulateCycleSystemGroup _simulateCycleSystemGroup; + // private BallRingCounterSystem _ballRingCounterSystem; + // private UpdateAnimationsSystemGroup _updateAnimationsSystemGroup; + // private TransformMeshesSystemGroup _transformMeshesSystemGroup; private readonly Queue _afterBallCreationQueue = new Queue(); private readonly Queue _beforeBallCreationQueue = new Queue(); @@ -60,22 +60,22 @@ protected override void OnCreate() Enabled = false; _time.Start(); - - _createBallEntityCommandBufferSystem = World.GetOrCreateSystemManaged(); - _velocitiesSystemGroup = World.GetOrCreateSystemManaged(); - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); + // + // _createBallEntityCommandBufferSystem = World.GetOrCreateSystemManaged(); + // _velocitiesSystemGroup = World.GetOrCreateSystemManaged(); + // _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); // todo re-enable system // _ballRingCounterSystem = World.GetOrCreateSystemManaged(); - _updateAnimationsSystemGroup = World.GetOrCreateSystemManaged(); - _transformMeshesSystemGroup = World.GetOrCreateSystemManaged(); + // _updateAnimationsSystemGroup = World.GetOrCreateSystemManaged(); + // _transformMeshesSystemGroup = World.GetOrCreateSystemManaged(); - _systemsToUpdate.Add(_createBallEntityCommandBufferSystem); - _systemsToUpdate.Add(_velocitiesSystemGroup); - _systemsToUpdate.Add(_simulateCycleSystemGroup); + // _systemsToUpdate.Add(_createBallEntityCommandBufferSystem); + // _systemsToUpdate.Add(_velocitiesSystemGroup); + // _systemsToUpdate.Add(_simulateCycleSystemGroup); // todo re-enable system // _systemsToUpdate.Add(_ballRingCounterSystem); - _systemsToUpdate.Add(_updateAnimationsSystemGroup); - _systemsToUpdate.Add(_transformMeshesSystemGroup); + // _systemsToUpdate.Add(_updateAnimationsSystemGroup); + // _systemsToUpdate.Add(_transformMeshesSystemGroup); base.OnCreate(); } @@ -92,33 +92,33 @@ protected override void OnUpdate() _beforeBallCreationQueue.Dequeue().Invoke(); } } - _createBallEntityCommandBufferSystem.Update(); + //_createBallEntityCommandBufferSystem.Update(); lock (_afterBallCreationQueue) { while (_afterBallCreationQueue.Count > 0) { _afterBallCreationQueue.Dequeue().Invoke(); } } - + //const int startTimeUsec = 0; var initialTimeUsec = GetTargetTime(); - + while (_currentPhysicsFrameTime < initialTimeUsec) { - + TimeMsec = (uint) (SystemAPI.Time.ElapsedTime * 1000); PhysicsDiffTime = (_nextPhysicsFrameTime - _currentPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime); - + // update velocities - _velocitiesSystemGroup.Update(); - + //_velocitiesSystemGroup.Update(); + // simulate cycle - _simulateCycleSystemGroup.Update(); - + //_simulateCycleSystemGroup.Update(); + // new cycle, on physics frame boundary _currentPhysicsFrameTime = _nextPhysicsFrameTime; - + // advance physics position _nextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; - + // run scheduled actions lock (_scheduledActions) { for (var i = _scheduledActions.Count - 1; i >= 0; i--) { @@ -129,16 +129,16 @@ protected override void OnUpdate() } } } - - _ballRingCounterSystem.Update(); - + + //_ballRingCounterSystem.Update(); + _currentPhysicsTime = _currentPhysicsFrameTime; - + // update animations - _updateAnimationsSystemGroup.Update(); - + //_updateAnimationsSystemGroup.Update(); + // transform all meshes - _transformMeshesSystemGroup.Update(); + //_transformMeshesSystemGroup.Update(); } private ulong GetTargetTime() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs index c0b1a5811..6ebea75b9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs @@ -293,7 +293,7 @@ private void Awake() private void Start() { _kickerApi = GetComponentInParent().TableApi.Kicker(this); - if (_kickerApi.KickerCoil != null) { + if (_kickerApi?.KickerCoil != null) { _originalKickerAngle = _kickerApi.KickerCoil.Coil.Angle; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs index ea4ad9d3c..cd025398b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs @@ -479,7 +479,7 @@ public bool EjectBall() if (_ejectKicker == null) { - Logger.Error("Trough: Cannot spawn ball without an exit kicker."); + Logger.Warn("Trough: Cannot spawn ball without an exit kicker."); return false; } Logger.Info("Trough: Spawning new ball."); From 5ec98bcee2879b8744d2ed914b6847f2e41a7b33 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 29 Jan 2023 00:09:13 +0100 Subject: [PATCH 030/159] jobs: Move state into struct. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 3 +- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 35 ++++++++----------- .../VisualPinball.Unity/Game/PhysicsState.cs | 34 ++++++++++++++++++ ...icsStatus.cs.meta => PhysicsState.cs.meta} | 0 .../VisualPinball.Unity/Game/PhysicsStatus.cs | 7 ---- 5 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs rename VisualPinball.Unity/VisualPinball.Unity/Game/{PhysicsStatus.cs.meta => PhysicsState.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index beb621db6..e403de550 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -15,13 +15,14 @@ // along with this program. If not, see . using UnityEngine; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinball.Unity { public static class PhysicsCycle { - public static void Simulate(float dTime) + public static void Simulate(float dTime, ref PhysicsState state) { while (dTime > 0) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 556f264ee..c704aa9b9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -20,30 +20,28 @@ using Unity.Jobs; using UnityEngine; using VisualPinball.Engine.Common; +using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinball.Unity { public class PhysicsEngine : MonoBehaviour { [NonSerialized] - private NativeArray _uSecs; + private NativeArray _physicsState; private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); private void Start() { - _uSecs = new NativeArray(3, Allocator.Persistent); - _uSecs[0] = NowUsec; // start time - _uSecs[1] = _uSecs[0]; // current time frame - _uSecs[2] = _uSecs[0] + PhysicsConstants.PhysicsStepTime; // next time frame + _physicsState = new NativeArray(1, Allocator.Persistent); + _physicsState[0] = new PhysicsState(NowUsec); } private void Update() { - var updatePhysics = new UpdatePhysicsJob { InitialTimeUsec = NowUsec, - USecs = _uSecs, + PhysicsState = _physicsState, }; updatePhysics.Run(); @@ -51,7 +49,7 @@ private void Update() private void OnDestroy() { - _uSecs.Dispose(); + _physicsState.Dispose(); } } @@ -61,30 +59,27 @@ public struct UpdatePhysicsJob : IJob [ReadOnly] public ulong InitialTimeUsec; - public NativeArray USecs; + public NativeArray PhysicsState; public void Execute() { var n = 0; - var startTimeUsec = USecs[0]; - var curPhysicsFrameTime = USecs[1]; - var nextPhysicsFrameTime = USecs[2]; + var state = PhysicsState[0]; - while (curPhysicsFrameTime < InitialTimeUsec) + while (state.CurPhysicsFrameTime < InitialTimeUsec) { - var timeMsec = (uint)((curPhysicsFrameTime - startTimeUsec) / 1000); - var physicsDiffTime = (float)((nextPhysicsFrameTime - curPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); + var timeMsec = (uint)((state.CurPhysicsFrameTime - state.StartTimeUsec) / 1000); + var physicsDiffTime = (float)((state.NextPhysicsFrameTime - state.CurPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); - PhysicsCycle.Simulate(physicsDiffTime); + PhysicsCycle.Simulate(physicsDiffTime, ref state); - curPhysicsFrameTime = nextPhysicsFrameTime; - nextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; + state.CurPhysicsFrameTime = state.NextPhysicsFrameTime; + state.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; n++; } - USecs[1] = curPhysicsFrameTime; - USecs[2] = nextPhysicsFrameTime; + PhysicsState[0] = state; //Debug.Log($"UpdatePhysic {n}x"); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs new file mode 100644 index 000000000..722e2fd27 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -0,0 +1,34 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.Common; + +namespace VisualPinball.Unity.VisualPinball.Unity.Game +{ + public struct PhysicsState + { + public readonly ulong StartTimeUsec; + public ulong CurPhysicsFrameTime; + public ulong NextPhysicsFrameTime; + + public PhysicsState(ulong startTimeUsec) : this() + { + StartTimeUsec = startTimeUsec; + CurPhysicsFrameTime = StartTimeUsec; + NextPhysicsFrameTime = StartTimeUsec + PhysicsConstants.PhysicsStepTime; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs deleted file mode 100644 index 03168de3c..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStatus.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace VisualPinball.Unity.VisualPinball.Unity.Game -{ - public struct PhysicsStatus - { - - } -} From 77eda95f602a1bb551a832a4bef9b0f62c399b47 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 1 Feb 2023 20:34:47 +0100 Subject: [PATCH 031/159] jobs: Create colliders and use bartofzo/NativeTrees for octree. --- .../VisualPinball.Unity/Game/PhysicsBall.cs | 42 ++++++++++++++ .../Game/PhysicsBall.cs.meta | 3 + .../VisualPinball.Unity/Game/PhysicsCycle.cs | 3 +- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 58 +++++++++++++++++-- .../VisualPinball.Unity/Game/PhysicsState.cs | 2 +- .../Physics/Collider/PlaneCollider.cs | 2 +- .../Physics/Collision/Aabb.cs | 8 +++ .../Physics/Collision/ColliderBounds.cs | 2 + .../VPT/ICollidableComponent.cs | 25 ++++++++ .../VPT/ICollidableComponent.cs.meta | 3 + .../VPT/Playfield/PlayfieldApi.cs | 1 - .../Playfield/PlayfieldColliderComponent.cs | 11 +++- .../VPT/Playfield/PlayfieldComponent.cs | 1 + .../VisualPinball.Unity.asmdef | 3 +- 14 files changed, 153 insertions(+), 11 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs new file mode 100644 index 000000000..50a32f71b --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs @@ -0,0 +1,42 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable InconsistentNaming + +using Unity.Mathematics; +using UnityEngine; + +namespace VisualPinball.Unity.VisualPinball.Unity.Game +{ + public class PhysicsBall : MonoBehaviour + { + public float Radius = 25; + public float Mass = 1; + + internal BallData Data => new BallData { + Id = 0, + IsFrozen = false, + Position = transform.localPosition.TranslateToVpx(), + Radius = Radius, + Mass = Mass, + Velocity = float3.zero, + BallOrientation = float3x3.identity, + BallOrientationForUnity = float3x3.identity, + RingCounterOldPos = 0, + AngularMomentum = float3.zero + }; + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs.meta new file mode 100644 index 000000000..2b5b35122 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a04fca20ce2246b9abf456441b587efd +timeCreated: 1678725159 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index e403de550..370876676 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using UnityEngine; -using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinball.Unity { @@ -28,7 +27,7 @@ public static void Simulate(float dTime, ref PhysicsState state) { var hitTime = dTime; // begin time search from now ... until delta ends - Debug.Log("PhysicsCycle.Simulate"); + //Debug.Log("PhysicsCycle.Simulate"); dTime -= hitTime; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index c704aa9b9..5103d8361 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -15,12 +15,14 @@ // along with this program. If not, see . using System; +using System.Diagnostics; +using NativeTrees; using Unity.Burst; using Unity.Collections; using Unity.Jobs; using UnityEngine; using VisualPinball.Engine.Common; -using VisualPinball.Unity.VisualPinball.Unity.Game; +using Debug = UnityEngine.Debug; namespace VisualPinball.Unity { @@ -28,13 +30,42 @@ public class PhysicsEngine : MonoBehaviour { [NonSerialized] private NativeArray _physicsState; - + + [NonSerialized] + private NativeList _colliders; + [NonSerialized] + private NativeOctree _octree; + private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); private void Start() { _physicsState = new NativeArray(1, Allocator.Persistent); _physicsState[0] = new PhysicsState(NowUsec); + + var sw = Stopwatch.StartNew(); + var colliderItems = GetComponentsInChildren(); + + Debug.Log($"Found {colliderItems.Length} collider items."); + _colliders = new NativeList(Allocator.Persistent); + foreach (var colliderItem in colliderItems) { + colliderItem.GetColliders(ref _colliders); + } + + var elapsedMs = sw.Elapsed.TotalMilliseconds; + var playfieldBounds = GetComponentInChildren().Bounds; + _octree = new NativeOctree(playfieldBounds, 32, 10, Allocator.Persistent); + + sw.Restart(); + var populateJob = new PopulatePhysicsJob { + Colliders = _colliders, + Octree = _octree, + }; + populateJob.Run(); + + _octree = populateJob.Octree; + + Debug.Log($"Octree of {_colliders.Length} constructed (colliders: {elapsedMs}ms, tree: {sw.Elapsed.TotalMilliseconds}ms)."); } private void Update() @@ -42,6 +73,7 @@ private void Update() var updatePhysics = new UpdatePhysicsJob { InitialTimeUsec = NowUsec, PhysicsState = _physicsState, + Octree = _octree, }; updatePhysics.Run(); @@ -50,16 +82,34 @@ private void Update() private void OnDestroy() { _physicsState.Dispose(); + _colliders.Dispose(); } } - [BurstCompile] - public struct UpdatePhysicsJob : IJob + [BurstCompile(CompileSynchronously = true)] + internal struct PopulatePhysicsJob : IJob + { + [ReadOnly] + public NativeList Colliders; + public NativeOctree Octree; + + public void Execute() + { + foreach (var collider in Colliders) { + Octree.Insert(collider, collider.Bounds); + } + } + } + + [BurstCompile(CompileSynchronously = true)] + internal struct UpdatePhysicsJob : IJob { [ReadOnly] public ulong InitialTimeUsec; public NativeArray PhysicsState; + + public NativeOctree Octree; public void Execute() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 722e2fd27..c2bca5fa1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -16,7 +16,7 @@ using VisualPinball.Engine.Common; -namespace VisualPinball.Unity.VisualPinball.Unity.Game +namespace VisualPinball.Unity { public struct PhysicsState { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index 260f0098b..4af8b8561 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -30,7 +30,7 @@ internal struct PlaneCollider : ICollider private readonly float3 _normal; private readonly float _distance; - public ColliderBounds Bounds => new ColliderBounds(_header.Entity, _header.Id, default); + public ColliderBounds Bounds => new ColliderBounds(_header.Entity, _header.Id, new Aabb(float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue)); public PlaneCollider(float3 normal, float distance, ColliderInfo info) : this() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs index 232ae0c34..3ff639436 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs @@ -32,6 +32,9 @@ public struct Aabb public float Height => math.abs(Top - Bottom); public float Depth => math.abs(ZLow - ZHigh); + public Vector3 Min => new Vector3(Left, Top, ZLow); + public Vector3 Max => new Vector3(Right, Bottom, ZHigh); + public Vector3 Center => new Vector3( (Right + Left) / 2f, (Bottom + Top) / 2f, @@ -93,6 +96,11 @@ public bool IntersectRect(Aabb rc) && ZLow <= rc.ZHigh // 0 <= -8.79384 && ZHigh >= rc.ZLow; // 90 >= 58.79945 } + + public static implicit operator NativeTrees.AABB(Aabb aabb) + { + return new NativeTrees.AABB(aabb.Min, aabb.Max); + } public override string ToString() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs index 0228d60e0..27b9fc4c1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs @@ -36,6 +36,8 @@ public ColliderBounds(Entity colliderEntity, int colliderId, Aabb aabb) Aabb = aabb; } + public static implicit operator NativeTrees.AABB(ColliderBounds b) => b.Aabb; + public override string ToString() { return $"{Aabb.ToString()} ({ColliderId}:{ColliderEntity})"; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs new file mode 100644 index 000000000..e32054680 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs @@ -0,0 +1,25 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Collections; + +namespace VisualPinball.Unity +{ + public interface ICollidableComponent + { + internal void GetColliders(ref NativeList colliders); + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs.meta new file mode 100644 index 000000000..96fb59c5d --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d18da5a17a8b436db01731cafce44a07 +timeCreated: 1678721087 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs index 0bd65fa64..fb80e7291 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using System.Collections.Generic; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.VPT; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs index d804d7298..0d30b91cf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs @@ -17,6 +17,7 @@ // ReSharper disable InconsistentNaming using System; +using Unity.Collections; using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Table; @@ -24,7 +25,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Collision/Playfield Collider")] - public class PlayfieldColliderComponent : ColliderComponent + public class PlayfieldColliderComponent : ColliderComponent, ICollidableComponent { #region Data @@ -56,5 +57,13 @@ public class PlayfieldColliderComponent : ColliderComponent GetPhysicsMaterialData(0, 0); protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) => new PlayfieldApi(gameObject, player); + + void ICollidableComponent.GetColliders(ref NativeList colliders) + { + var api = new PlayfieldApi(gameObject, GetComponent()); + var c = api.CreateColliders(); + colliders.Add(c.Item1); + colliders.Add(c.Item2); + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs index 3a1a208f8..cde449e1c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs @@ -92,6 +92,7 @@ public class PlayfieldComponent : MainRenderableComponent protected override Type ColliderComponentType => typeof(PlayfieldColliderComponent); public Rect3D BoundingBox => new Rect3D(Left, Right, Top, Bottom, TableHeight, GlassHeight); + public Aabb Bounds => new Aabb(Left, Right, Top, Bottom, TableHeight, GlassHeight); public float3 Gravity { get { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VisualPinball.Unity.asmdef b/VisualPinball.Unity/VisualPinball.Unity/VisualPinball.Unity.asmdef index 421081b06..bcbe3a323 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VisualPinball.Unity.asmdef +++ b/VisualPinball.Unity/VisualPinball.Unity/VisualPinball.Unity.asmdef @@ -10,7 +10,8 @@ "Unity.Mathematics.Extensions", "Unity.Transforms", "Unity.InputSystem", - "VisualPinball.Engine" + "VisualPinball.Engine", + "com.bartofzo.nativetrees" ], "includePlatforms": [], "excludePlatforms": [], From 2f3c3ba9a02e4dbece54fe133e1ff46c5b914176 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 5 Feb 2023 21:13:36 +0100 Subject: [PATCH 032/159] jobs: Set up inner loop. --- .../VisualPinball.Unity/Game/PhysicsBall.cs | 14 ++++- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 51 ++++++++++++++++--- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 41 +++++++++------ .../VisualPinball.Unity/Game/Player.cs | 3 ++ 4 files changed, 87 insertions(+), 22 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs index 50a32f71b..fcdcc9763 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs @@ -16,6 +16,7 @@ // ReSharper disable InconsistentNaming +using System; using Unity.Mathematics; using UnityEngine; @@ -25,9 +26,20 @@ public class PhysicsBall : MonoBehaviour { public float Radius = 25; public float Mass = 1; + + [NonSerialized] + public int Id; + + private void Awake() + { + var player = GetComponentInParent(); + if (player) { + Id = player.NextBallId; + } + } internal BallData Data => new BallData { - Id = 0, + Id = Id, IsFrozen = false, Position = transform.localPosition.TranslateToVpx(), Radius = Radius, diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 370876676..12a8e4a6a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -14,23 +14,62 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using UnityEngine; +using System; +using NativeTrees; +using Unity.Collections; namespace VisualPinball.Unity { - public static class PhysicsCycle + public struct PhysicsCycle : IDisposable { + private NativeList _contacts; - public static void Simulate(float dTime, ref PhysicsState state) + public PhysicsCycle(Allocator a) { - while (dTime > 0) - { + _contacts = new NativeList(a); + } + + internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree octree, ref NativeList balls) + { + while (dTime > 0) { + var hitTime = dTime; // begin time search from now ... until delta ends - //Debug.Log("PhysicsCycle.Simulate"); + // todo apply flipper time + + // clear contacts + _contacts.Clear(); + + // todo dynamic broad phase + + // todo static broad phase + + // todo static narrow phase + + // todo dynamic narrow phase + + // todo apply static time + + // todo displacement + + // todo dynamic collision + + // todo static collision + + // todo handle contacts + + // clear contacts + _contacts.Clear(); + + // todo ball spin hack dTime -= hitTime; } } + + public void Dispose() + { + _contacts.Dispose(); + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 5103d8361..131aceb50 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -16,40 +16,40 @@ using System; using System.Diagnostics; +using System.Linq; using NativeTrees; using Unity.Burst; using Unity.Collections; using Unity.Jobs; using UnityEngine; using VisualPinball.Engine.Common; +using VisualPinball.Unity.VisualPinball.Unity.Game; using Debug = UnityEngine.Debug; namespace VisualPinball.Unity { public class PhysicsEngine : MonoBehaviour { - [NonSerialized] - private NativeArray _physicsState; - - [NonSerialized] - private NativeList _colliders; - [NonSerialized] - private NativeOctree _octree; + [NonSerialized] private NativeArray _physicsState; + [NonSerialized] private NativeOctree _octree; + [NonSerialized] private NativeList _balls; private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); private void Start() { + // init state _physicsState = new NativeArray(1, Allocator.Persistent); _physicsState[0] = new PhysicsState(NowUsec); + // create static octree var sw = Stopwatch.StartNew(); var colliderItems = GetComponentsInChildren(); Debug.Log($"Found {colliderItems.Length} collider items."); - _colliders = new NativeList(Allocator.Persistent); + var colliders = new NativeList(Allocator.TempJob); foreach (var colliderItem in colliderItems) { - colliderItem.GetColliders(ref _colliders); + colliderItem.GetColliders(ref colliders); } var elapsedMs = sw.Elapsed.TotalMilliseconds; @@ -58,14 +58,20 @@ private void Start() sw.Restart(); var populateJob = new PopulatePhysicsJob { - Colliders = _colliders, + Colliders = colliders, Octree = _octree, }; populateJob.Run(); - _octree = populateJob.Octree; - - Debug.Log($"Octree of {_colliders.Length} constructed (colliders: {elapsedMs}ms, tree: {sw.Elapsed.TotalMilliseconds}ms)."); + Debug.Log($"Octree of {colliders.Length} constructed (colliders: {elapsedMs}ms, tree: {sw.Elapsed.TotalMilliseconds}ms)."); + colliders.Dispose(); + + // get balls + var balls = GetComponentsInChildren(); + _balls = new NativeList(balls.Length, Allocator.Persistent); + foreach (var ball in balls) { + _balls.Add(ball.Data); + } } private void Update() @@ -74,6 +80,7 @@ private void Update() InitialTimeUsec = NowUsec, PhysicsState = _physicsState, Octree = _octree, + Balls = _balls, }; updatePhysics.Run(); @@ -82,7 +89,7 @@ private void Update() private void OnDestroy() { _physicsState.Dispose(); - _colliders.Dispose(); + _balls.Dispose(); } } @@ -111,17 +118,20 @@ internal struct UpdatePhysicsJob : IJob public NativeOctree Octree; + public NativeList Balls; + public void Execute() { var n = 0; var state = PhysicsState[0]; + var cycle = new PhysicsCycle(Allocator.Temp); while (state.CurPhysicsFrameTime < InitialTimeUsec) { var timeMsec = (uint)((state.CurPhysicsFrameTime - state.StartTimeUsec) / 1000); var physicsDiffTime = (float)((state.NextPhysicsFrameTime - state.CurPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); - PhysicsCycle.Simulate(physicsDiffTime, ref state); + cycle.Simulate(physicsDiffTime, ref state, ref Octree, ref Balls); state.CurPhysicsFrameTime = state.NextPhysicsFrameTime; state.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; @@ -130,6 +140,7 @@ public void Execute() } PhysicsState[0] = state; + cycle.Dispose(); //Debug.Log($"UpdatePhysic {n}x"); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 169352359..c9dcc9e7e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -121,6 +121,9 @@ public class Player : MonoBehaviour public Dictionary WireStatuses => _wirePlayer.WireStatuses; public float3 Gravity => _playfieldComponent.Gravity; + public int NextBallId => ++_currentBallId; + private int _currentBallId; + public void SetLamp(string lampId, float value) => _lampPlayer.HandleLampEvent(lampId, value); public void SetLamp(string lampId, LampStatus status) => _lampPlayer.HandleLampEvent(lampId, status); public void SetLamp(string lampId, Color color) => _lampPlayer.HandleLampEvent(lampId, color); From bd69c0baf445c7fde9123879ee32473b2b864b44 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 11 Feb 2023 23:19:22 +0100 Subject: [PATCH 033/159] jobs: Replace entities with IDs, and add static narrow phase. --- .../VisualPinball.Unity/Game/DeviceSwitch.cs | 5 +- .../VisualPinball.Unity/Game/PhysicsBall.cs | 1 + .../VisualPinball.Unity/Game/PhysicsCycle.cs | 23 +- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 1 - .../Game/PhysicsStaticBroadPhase.cs | 35 +++ .../Game/PhysicsStaticBroadPhase.cs.meta | 3 + .../Game/PhysicsStaticNarrowPhase.cs | 77 +++++++ .../Game/PhysicsStaticNarrowPhase.cs.meta | 3 + .../VisualPinball.Unity/Game/Player.cs | 162 +++++++------- .../Game/SystemBaseStub.cs | 4 + .../Physics/Collider/CircleCollider.cs | 8 +- .../Physics/Collider/Collider.cs | 27 ++- .../Physics/Collider/ColliderInfo.cs | 2 +- .../Physics/Collider/Line3DCollider.cs | 6 +- .../Physics/Collider/LineCollider.cs | 10 +- .../Physics/Collider/LineSlingshotCollider.cs | 6 +- .../Physics/Collider/LineZCollider.cs | 6 +- .../Physics/Collider/PlaneCollider.cs | 4 +- .../Physics/Collider/PointCollider.cs | 6 +- .../Physics/Collider/TriangleCollider.cs | 8 +- .../Physics/Collision/ColliderBounds.cs | 12 +- .../Physics/Collision/ColliderHeader.cs | 6 +- .../Physics/Collision/ContactBufferElement.cs | 6 +- .../Physics/Collision/ContactSystem.cs | 12 +- .../Collision/DynamicNarrowPhaseSystem.cs | 2 +- .../Physics/Collision/QuadTree.cs | 10 +- .../Physics/Collision/QuadTreeCreator.cs | 15 +- .../Collision/StaticCollisionSystem.cs | 107 ++++----- .../Collision/StaticNarrowPhaseSystem.cs | 50 ++--- .../Physics/DebugUI/IDebugUI.cs | 4 +- .../Physics/Engine/DefaultPhysicsEngine.cs | 30 +-- .../Physics/Engine/IPhysicsEngine.cs | 10 +- .../Physics/Event/EventData.cs | 28 +-- .../VisualPinball.Unity/VPT/Ball/BallData.cs | 20 +- .../VPT/Ball/BallInsideOfBufferElement.cs | 2 +- .../VPT/Ball/BallManager.cs | 64 +++--- .../VPT/Ball/BallMovementSystem.cs | 75 +++---- .../VPT/Bumper/BumperApi.cs | 20 +- .../VPT/Bumper/BumperBaker.cs | 2 +- .../VPT/Bumper/BumperCollider.cs | 4 +- .../VPT/Bumper/BumperColliderComponent.cs | 5 +- .../VPT/Bumper/BumperRingMovementSystem.cs | 43 ++-- .../VPT/Bumper/BumperSkirtMovementSystem.cs | 25 ++- .../VisualPinball.Unity/VPT/CollidableApi.cs | 21 +- .../VPT/ColliderComponent.cs | 4 +- .../VPT/CollisionSwitch/CollisionSwitchApi.cs | 2 +- .../VisualPinball.Unity/VPT/EventArgs.cs | 12 +- .../VPT/Flipper/FlipperApi.cs | 24 +- .../VPT/Flipper/FlipperBaker.cs | 2 +- .../VPT/Flipper/FlipperCollider.cs | 8 +- .../VPT/Flipper/FlipperColliderComponent.cs | 4 +- .../VPT/Flipper/FlipperDisplacementSystem.cs | 127 +++++------ .../VPT/Flipper/FlipperRotateSystem.cs | 21 +- .../VisualPinball.Unity/VPT/Gate/GateApi.cs | 22 +- .../VisualPinball.Unity/VPT/Gate/GateBaker.cs | 2 +- .../VPT/Gate/GateCollider.cs | 4 +- .../VPT/Gate/GateColliderComponent.cs | 4 +- .../VPT/Gate/GateDisplacementSystem.cs | 163 +++++++------- .../VPT/Gate/GateMovementSystem.cs | 21 +- .../HitTarget/DropTargetAnimationSystem.cs | 115 +++++----- .../VPT/HitTarget/DropTargetApi.cs | 46 ++-- .../VPT/HitTarget/DropTargetBaker.cs | 2 +- .../HitTarget/DropTargetColliderComponent.cs | 4 +- .../DropTargetTransformationSystem.cs | 31 +-- .../VPT/HitTarget/HitTargetApi.cs | 10 +- .../VPT/HitTarget/HitTargetBaker.cs | 2 +- .../HitTarget/HitTargetColliderComponent.cs | 4 +- .../HitTargetTransformationSystem.cs | 33 +-- .../VPT/HitTarget/TargetCollider.cs | 8 +- .../VisualPinball.Unity/VPT/IApi.cs | 13 +- .../VPT/Kicker/KickerApi.cs | 205 +++++++++--------- .../VPT/Kicker/KickerBaker.cs | 7 +- .../VPT/Kicker/KickerCollider.cs | 18 +- .../VPT/Kicker/KickerColliderComponent.cs | 4 +- .../VPT/Kicker/KickerCollisionData.cs | 6 +- .../VPT/Mech/RotatorComponent.cs | 37 ++-- .../VPT/MetalWireGuide/MetalWireGuideApi.cs | 7 +- .../VPT/MetalWireGuide/MetalWireGuideBaker.cs | 2 +- .../MetalWireGuideColliderComponent.cs | 4 +- .../VPT/Playfield/PlayfieldApi.cs | 6 +- .../Playfield/PlayfieldColliderComponent.cs | 4 +- .../VPT/Plunger/PlungerApi.cs | 104 ++++----- .../VPT/Plunger/PlungerBaker.cs | 4 +- .../VPT/Plunger/PlungerCollider.cs | 2 +- .../VPT/Plunger/PlungerColliderComponent.cs | 4 +- .../VPT/Plunger/PlungerDisplacementSystem.cs | 159 +++++++------- .../Plunger/PlungerTransformationSystem.cs | 21 +- .../VPT/Primitive/PrimitiveApi.cs | 7 +- .../VPT/Primitive/PrimitiveBaker.cs | 2 +- .../Primitive/PrimitiveColliderComponent.cs | 4 +- .../VisualPinball.Unity/VPT/Ramp/RampApi.cs | 10 +- .../VisualPinball.Unity/VPT/Ramp/RampBaker.cs | 2 +- .../VPT/Ramp/RampColliderComponent.cs | 4 +- .../VPT/Rubber/RubberApi.cs | 7 +- .../VPT/Rubber/RubberBaker.cs | 2 +- .../VPT/Rubber/RubberColliderComponent.cs | 4 +- .../VPT/Spinner/SpinnerApi.cs | 5 +- .../VPT/Spinner/SpinnerBaker.cs | 2 +- .../VPT/Spinner/SpinnerColliderComponent.cs | 4 +- .../VPT/Spinner/SpinnerDisplacementSystem.cs | 139 ++++++------ .../VPT/Spinner/SpinnerMovementSystem.cs | 21 +- .../VPT/Surface/SlingshotApi.cs | 5 +- .../VPT/Surface/SurfaceApi.cs | 12 +- .../VPT/Surface/SurfaceBaker.cs | 2 +- .../VPT/Surface/SurfaceColliderComponent.cs | 4 +- .../VPT/Trigger/TriggerApi.cs | 15 +- .../VPT/Trigger/TriggerBaker.cs | 2 +- .../VPT/Trigger/TriggerCollider.cs | 12 +- .../VPT/Trigger/TriggerColliderComponent.cs | 4 +- .../VPT/Trigger/TriggerMovementSystem.cs | 33 +-- .../VPT/Trough/TroughApi.cs | 2 +- 111 files changed, 1360 insertions(+), 1196 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs index 1c4b945b6..3ede130b5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using System; -using Unity.Entities; namespace VisualPinball.Unity { @@ -71,7 +70,7 @@ IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchS public void SetSwitch(bool enabled) { _switchHandler.OnSwitch(enabled); - Switch?.Invoke(this, new SwitchEventArgs(enabled, Entity.Null)); + Switch?.Invoke(this, new SwitchEventArgs(enabled)); } /// @@ -85,7 +84,7 @@ public void ScheduleSwitch(bool enabled, int delay) SetSwitch(enabled); } else { _switchHandler.ScheduleSwitch(enabled, delay, isEnabled => { - Switch?.Invoke(this, new SwitchEventArgs(isEnabled, Entity.Null)); + Switch?.Invoke(this, new SwitchEventArgs(isEnabled)); }); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs index fcdcc9763..1ff763433 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs @@ -17,6 +17,7 @@ // ReSharper disable InconsistentNaming using System; +using Unity.Collections; using Unity.Mathematics; using UnityEngine; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 12a8e4a6a..cc360fc2b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -23,10 +23,12 @@ namespace VisualPinball.Unity public struct PhysicsCycle : IDisposable { private NativeList _contacts; + private NativeList _overlappingColliders; public PhysicsCycle(Allocator a) { _contacts = new NativeList(a); + _overlappingColliders = new NativeList(a); } internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree octree, ref NativeList balls) @@ -41,10 +43,24 @@ internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree. + +using NativeTrees; +using Unity.Collections; +using Unity.Profiling; + +namespace VisualPinball.Unity +{ + public static class PhysicsStaticBroadPhase + { + private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("StaticBroadPhase"); + + internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeList overlappingColliders) + { + PerfMarker.Begin(); + overlappingColliders.Clear(); + octree.RangeAABB(ball.Aabb, overlappingColliders); + PerfMarker.End(); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs.meta new file mode 100644 index 000000000..7b50c62e2 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0cf814a76e55460fb3a3232176ead728 +timeCreated: 1678825180 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs new file mode 100644 index 000000000..4afebd35f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -0,0 +1,77 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Collections; +using Unity.Profiling; +using UnityEngine; + +namespace VisualPinball.Unity +{ + public static class PhysicsStaticNarrowPhase + { + private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("StaticNarrowPhase"); + + internal static void FindNextCollision(float hitTime, ref BallData ball, in NativeList overlappingColliders, + ref NativeList contacts) + { + PerfMarker.Begin(); + + // init contacts and event + ball.CollisionEvent.ClearCollider(hitTime); // search upto current hit time + + foreach (var coll in overlappingColliders) + { + var newCollEvent = new CollisionEventData(); + float newTime = 0; + + HitTest(ref ball, in coll, ref contacts); + SaveCollisions(ref ball, ref newCollEvent, ref contacts, in coll, newTime); + } + + // no negative time allowed + if (ball.CollisionEvent.HitTime < 0) { + ball.CollisionEvent.ClearCollider(); + } + + PerfMarker.End(); + } + + private static void HitTest(ref BallData ball, in PlaneCollider coll, ref NativeList contacts) { + + var newCollEvent = new CollisionEventData(); + var newTime = Collider.HitTest(ref ball, in coll, ball.CollisionEvent.HitTime); + + SaveCollisions(ref ball, ref newCollEvent, ref contacts, in coll, newTime); + } + + private static void SaveCollisions(ref BallData ball, ref CollisionEventData newCollEvent, + ref NativeList contacts, in PlaneCollider coll, float newTime) + { + var validHit = newTime >= 0f && !Math.Sign(newTime) && newTime <= ball.CollisionEvent.HitTime; + + if (newCollEvent.IsContact || validHit) { + newCollEvent.SetCollider(coll.Id); + newCollEvent.HitTime = newTime; + if (newCollEvent.IsContact) { + contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); + + } else { // if (validhit) + ball.CollisionEvent = newCollEvent; + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs.meta new file mode 100644 index 000000000..7d1b87346 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a04a4f7580b94ee6af69ff781069ce5f +timeCreated: 1678831337 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index c9dcc9e7e..e886b38cc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -66,23 +66,23 @@ public class Player : MonoBehaviour // table related private readonly List _apis = new List(); private readonly List _colliderGenerators = new List(); - private readonly Dictionary _hittables = new Dictionary(); - private readonly Dictionary _rotatables = new Dictionary(); - private readonly Dictionary _collidables = new Dictionary(); - private readonly Dictionary _spinnables = new Dictionary(); - private readonly Dictionary _slingshots = new Dictionary(); - private readonly Dictionary _droppables = new Dictionary(); - - internal readonly Dictionary FlipperTransforms = new Dictionary(); - internal readonly Dictionary BumperSkirtTransforms = new Dictionary(); - internal readonly Dictionary BumperRingTransforms = new Dictionary(); - internal readonly Dictionary GateWireTransforms = new Dictionary(); - internal readonly Dictionary HitTargetTransforms = new Dictionary(); - internal readonly Dictionary DropTargetTransforms = new Dictionary(); - internal readonly Dictionary SpinnerPlateTransforms = new Dictionary(); - internal readonly Dictionary TriggerTransforms = new Dictionary(); - internal readonly Dictionary PlungerSkinnedMeshRenderers = new Dictionary(); - internal readonly Dictionary Balls = new Dictionary(); + private readonly Dictionary _hittables = new Dictionary(); + private readonly Dictionary _rotatables = new Dictionary(); + private readonly Dictionary _collidables = new Dictionary(); + private readonly Dictionary _spinnables = new Dictionary(); + private readonly Dictionary _slingshots = new Dictionary(); + private readonly Dictionary _droppables = new Dictionary(); + + internal readonly Dictionary FlipperTransforms = new Dictionary(); + internal readonly Dictionary BumperSkirtTransforms = new Dictionary(); + internal readonly Dictionary BumperRingTransforms = new Dictionary(); + internal readonly Dictionary GateWireTransforms = new Dictionary(); + internal readonly Dictionary HitTargetTransforms = new Dictionary(); + internal readonly Dictionary DropTargetTransforms = new Dictionary(); + internal readonly Dictionary SpinnerPlateTransforms = new Dictionary(); + internal readonly Dictionary TriggerTransforms = new Dictionary(); + internal readonly Dictionary PlungerSkinnedMeshRenderers = new Dictionary(); + internal readonly Dictionary Balls = new Dictionary(); internal IEnumerable ColliderGenerators => _colliderGenerators; @@ -216,33 +216,33 @@ private void OnDestroy() #region Registrations - public void RegisterBumper(BumperComponent component, Entity entity) + public void RegisterBumper(BumperComponent component) { - Register(new BumperApi(component.gameObject, entity, this), component, entity); - RegisterTransform(BumperRingTransforms, component, entity); - RegisterTransform(BumperSkirtTransforms, component, entity); + Register(new BumperApi(component.gameObject, this), component); + RegisterTransform(BumperRingTransforms, component); + RegisterTransform(BumperSkirtTransforms, component); } - public void RegisterFlipper(FlipperComponent component, Entity entity) + public void RegisterFlipper(FlipperComponent component) { - Register(new FlipperApi(component.gameObject, entity, this), component, entity); - FlipperTransforms[entity] = component.gameObject.transform; + Register(new FlipperApi(component.gameObject, this), component); + FlipperTransforms[component.GetInstanceID()] = component.gameObject.transform; if (EngineProvider.Exists) { - EngineProvider.Get().OnRegisterFlipper(entity, component.gameObject.name); + EngineProvider.Get().OnRegisterFlipper(component.GetInstanceID(), component.gameObject.name); } } - public void RegisterDropTarget(DropTargetComponent component, Entity entity) + public void RegisterDropTarget(DropTargetComponent component) { - Register(new DropTargetApi(component.gameObject, entity, this), component, entity); - RegisterTransform(DropTargetTransforms, component, entity); + Register(new DropTargetApi(component.gameObject, this), component); + RegisterTransform(DropTargetTransforms, component); } - public void RegisterGate(GateComponent component, Entity entity) + public void RegisterGate(GateComponent component) { - Register(new GateApi(component.gameObject, entity, this), component, entity); - RegisterTransform(GateWireTransforms, component, entity); + Register(new GateApi(component.gameObject, this), component); + RegisterTransform(GateWireTransforms, component); } public void RegisterGateLifter(GateLifterComponent component) @@ -250,15 +250,15 @@ public void RegisterGateLifter(GateLifterComponent component) Register(new GateLifterApi(component.gameObject, this), component); } - public void RegisterHitTarget(HitTargetComponent component, Entity entity) + public void RegisterHitTarget(HitTargetComponent component) { - Register(new HitTargetApi(component.gameObject, entity, this), component, entity); - RegisterTransform(HitTargetTransforms, component, entity); + Register(new HitTargetApi(component.gameObject, this), component); + RegisterTransform(HitTargetTransforms, component); } - public void RegisterKicker(KickerComponent component, Entity entity) + public void RegisterKicker(KickerComponent component) { - Register(new KickerApi(component.gameObject, entity, this), component, entity); + Register(new KickerApi(component.gameObject, this), component); } public void RegisterLamp(LightComponent component) @@ -296,17 +296,17 @@ public void RegisterSlingshotComponent(SlingshotComponent component) Register(new SlingshotApi(component.gameObject, this), component); } - public void RegisterPlunger(PlungerComponent component, Entity entity, InputActionReference actionRef) + public void RegisterPlunger(PlungerComponent component, InputActionReference actionRef) { - var plungerApi = new PlungerApi(component.gameObject, entity, this); - Register(plungerApi, component, entity); + var plungerApi = new PlungerApi(component.gameObject, this); + Register(plungerApi, component); if (actionRef != null) { actionRef.action.performed += plungerApi.OnAnalogPlunge; _actions.Add((actionRef.action, plungerApi.OnAnalogPlunge)); } - PlungerSkinnedMeshRenderers[entity] = component.gameObject.GetComponentsInChildren(); + PlungerSkinnedMeshRenderers[component.GetInstanceID()] = component.gameObject.GetComponentsInChildren(); } public void RegisterPlayfield(GameObject go) @@ -315,30 +315,30 @@ public void RegisterPlayfield(GameObject go) _colliderGenerators.Add(PlayfieldApi); } - public void RegisterPrimitive(PrimitiveComponent component, Entity entity) + public void RegisterPrimitive(PrimitiveComponent component) { - Register(new PrimitiveApi(component.gameObject, entity, this), component, entity); + Register(new PrimitiveApi(component.gameObject, this), component, component.gameObject.GetInstanceID()); } - public void RegisterRamp(RampComponent component, Entity entity) + public void RegisterRamp(RampComponent component) { - Register(new RampApi(component.gameObject, entity, this), component, entity); + Register(new RampApi(component.gameObject, this), component); } - public void RegisterRubber(RubberComponent component, Entity entity) + public void RegisterRubber(RubberComponent component) { - Register(new RubberApi(component.gameObject, entity, this), component, entity); + Register(new RubberApi(component.gameObject, this), component); } - public void RegisterSpinner(SpinnerComponent component, Entity entity) + public void RegisterSpinner(SpinnerComponent component) { - Register(new SpinnerApi(component.gameObject, entity, this), component, entity); - RegisterTransform(SpinnerPlateTransforms, component, entity); + Register(new SpinnerApi(component.gameObject, this), component); + RegisterTransform(SpinnerPlateTransforms, component); } - public void RegisterSurface(SurfaceComponent component, Entity entity) + public void RegisterSurface(SurfaceComponent component) { - Register(new SurfaceApi(component.gameObject, entity, this), component, entity); + Register(new SurfaceApi(component.gameObject, this), component); } public void RegisterTeleporter(TeleporterComponent component) @@ -346,17 +346,17 @@ public void RegisterTeleporter(TeleporterComponent component) Register(new TeleporterApi(component.gameObject, this), component); } - public void RegisterTrigger(TriggerComponent component, Entity entity) + public void RegisterTrigger(TriggerComponent component) { - Register(new TriggerApi(component.gameObject, entity, this), component, entity); - TriggerTransforms[entity] = component.gameObject.transform; + Register(new TriggerApi(component.gameObject, this), component); + TriggerTransforms[component.GetInstanceID()] = component.gameObject.transform; } - public void RegisterTrigger(TriggerData data, Entity entity, GameObject go) + public void RegisterTrigger(TriggerData data, GameObject go) { var component = go.AddComponent(); component.SetData(data); - Register(new TriggerApi(go, entity, this), component, entity); + Register(new TriggerApi(go, this), component); } public void RegisterTrough(TroughComponent component) @@ -364,26 +364,26 @@ public void RegisterTrough(TroughComponent component) Register(new TroughApi(component.gameObject, this), component); } - public void RegisterMetalWireGuide(MetalWireGuideComponent component, Entity entity) + public void RegisterMetalWireGuide(MetalWireGuideComponent component) { - Register(new MetalWireGuideApi(component.gameObject, entity, this), component, entity); + Register(new MetalWireGuideApi(component.gameObject, this), component); } - private void Register(TApi api, MonoBehaviour component, Entity entity = default) where TApi : IApi + private void Register(TApi api, MonoBehaviour component, int itemId = 0) where TApi : IApi { TableApi.Register(component, api); _apis.Add(api); if (api is IApiRotatable rotatable) { - _rotatables[entity] = rotatable; + _rotatables[itemId] = rotatable; } if (api is IApiSlingshot slingshot) { - _slingshots[entity] = slingshot; + _slingshots[itemId] = slingshot; } if (api is IApiDroppable droppable) { - _droppables[entity] = droppable; + _droppables[itemId] = droppable; } if (api is IApiSpinnable spinnable) { - _spinnables[entity] = spinnable; + _spinnables[itemId] = spinnable; } if (api is IApiSwitchDevice switchDevice) { if (component is ISwitchDeviceComponent switchDeviceComponent) { @@ -416,30 +416,30 @@ private void Register(TApi api, MonoBehaviour component, Entity entity = d } if (api is IApiColliderGenerator colliderGenerator) { - RegisterCollider(entity, colliderGenerator); + RegisterCollider(itemId, colliderGenerator); } } - private void RegisterTransform(Dictionary transforms, MonoBehaviour component, Entity entity) where T : MonoBehaviour + private void RegisterTransform(Dictionary transforms, MonoBehaviour component) where T : MonoBehaviour { var comp = component.gameObject.GetComponentInChildren(); if (comp) { - transforms[entity] = comp.gameObject.transform; + transforms[component.GetInstanceID()] = comp.gameObject.transform; } } - private void RegisterCollider(Entity entity, IApiColliderGenerator apiColl) + private void RegisterCollider(int itemId, IApiColliderGenerator apiColl) { if (!apiColl.IsColliderAvailable) { return; } _colliderGenerators.Add(apiColl); if (apiColl is IApiHittable apiHittable) { - _hittables[entity] = apiHittable; + _hittables[itemId] = apiHittable; } if (apiColl is IApiCollidable apiCollidable) { - _collidables[entity] = apiCollidable; + _collidables[itemId] = apiCollidable; } } @@ -455,46 +455,46 @@ public void OnEvent(in EventData eventData) { switch (eventData.eventId) { case EventId.HitEventsHit: - if (!_hittables.ContainsKey(eventData.ItemEntity)) { - Debug.LogError($"Cannot find entity {eventData.ItemEntity} in hittables."); + if (!_hittables.ContainsKey(eventData.ItemId)) { + Debug.LogError($"Cannot find entity {eventData.ItemId} in hittables."); } - _hittables[eventData.ItemEntity].OnHit(eventData.BallEntity); + _hittables[eventData.ItemId].OnHit(eventData.BallId); break; case EventId.HitEventsUnhit: - _hittables[eventData.ItemEntity].OnHit(eventData.BallEntity, true); + _hittables[eventData.ItemId].OnHit(eventData.BallId, true); break; case EventId.LimitEventsBos: - _rotatables[eventData.ItemEntity].OnRotate(eventData.FloatParam, false); + _rotatables[eventData.ItemId].OnRotate(eventData.FloatParam, false); break; case EventId.LimitEventsEos: - _rotatables[eventData.ItemEntity].OnRotate(eventData.FloatParam, true); + _rotatables[eventData.ItemId].OnRotate(eventData.FloatParam, true); break; case EventId.SpinnerEventsSpin: - _spinnables[eventData.ItemEntity].OnSpin(); + _spinnables[eventData.ItemId].OnSpin(); break; case EventId.FlipperEventsCollide: - _collidables[eventData.ItemEntity].OnCollide(eventData.BallEntity, eventData.FloatParam); + _collidables[eventData.ItemId].OnCollide(eventData.BallId, eventData.FloatParam); break; case EventId.SurfaceEventsSlingshot: - _slingshots[eventData.ItemEntity].OnSlingshot(eventData.BallEntity); + _slingshots[eventData.ItemId].OnSlingshot(eventData.BallId); break; case EventId.TargetEventsDropped: - _droppables[eventData.ItemEntity].OnDropStatusChanged(true, eventData.BallEntity); + _droppables[eventData.ItemId].OnDropStatusChanged(true, eventData.BallId); break; case EventId.TargetEventsRaised: - _droppables[eventData.ItemEntity].OnDropStatusChanged(false, eventData.BallEntity); + _droppables[eventData.ItemId].OnDropStatusChanged(false, eventData.BallId); break; default: - throw new InvalidOperationException($"Unknown event {eventData.eventId} for entity {eventData.ItemEntity}"); + throw new InvalidOperationException($"Unknown event {eventData.eventId} for entity {eventData.ItemId}"); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs index 58a8779c3..e9e8905c3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs @@ -23,10 +23,14 @@ public void Update() { } protected internal LambdaSingleJobDescription Job => new LambdaSingleJobDescription(); protected internal T GetComponent(Entity entity) where T : unmanaged, IComponentData => EntityManager.GetComponentData(entity); + protected internal T GetComponent(int itemId) where T : unmanaged, IComponentData => default; protected internal void SetComponent(Entity entity, T component) where T : unmanaged, IComponentData => EntityManager.SetComponentData(entity, component); + protected internal void SetComponent(int itemId, T component) where T : unmanaged, IComponentData { } + protected internal bool HasComponent(Entity entity) where T : unmanaged, IComponentData => false; + protected internal bool HasComponent(int itemId) where T : unmanaged, IComponentData => false; protected internal EntityQuery GetEntityQuery(params ComponentType[] componentTypes) => default; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs index ac4a7f963..6d4bd4993 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs @@ -35,7 +35,7 @@ internal struct CircleCollider : ICollider private readonly float _zHigh; private readonly float _zLow; - public ColliderBounds Bounds => new ColliderBounds(_header.Entity, _header.Id, new Aabb( + public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( Center.x - Radius, Center.x + Radius, Center.y - Radius, @@ -129,7 +129,7 @@ public float HitTestBasicRadius(ref CollisionEventData collEvent, ref DynamicBuf // Kicker is special.. handle ball stalled on kicker, commonly hit while receding, knocking back into kicker pocket if (isKicker && bnd <= 0 && bnd >= -Radius && a < PhysicsConstants.ContactVel * PhysicsConstants.ContactVel/* && ball.Hit.IsRealBall()*/) { - BallData.SetOutsideOf(ref insideOfs, _header.Entity); + BallData.SetOutsideOf(ref insideOfs, _header.ItemId); } // contact positive possible in future ... objects Negative in contact now @@ -149,13 +149,13 @@ public float HitTestBasicRadius(ref CollisionEventData collEvent, ref DynamicBuf hitTime = math.max(0.0f, (float) (-bnd / bnv)); } - } else if (isKickerOrTrigger /*&& ball.Hit.IsRealBall()*/ && bnd < 0 == BallData.IsOutsideOf(in insideOfs, in _header.Entity)) { + } else if (isKickerOrTrigger /*&& ball.Hit.IsRealBall()*/ && bnd < 0 == BallData.IsOutsideOf(in insideOfs, in _header.ItemId)) { // triggers & kickers // here if ... ball inside and no hit set .... or ... ball outside and hit set if (math.abs(bnd - Radius) < 0.05) { // if ball appears in center of trigger, then assumed it was gen"ed there - BallData.SetInsideOf(ref insideOfs, _header.Entity); // special case for trigger overlaying a kicker + BallData.SetInsideOf(ref insideOfs, _header.ItemId); // special case for trigger overlaying a kicker } else { // this will add the ball to the trigger space without a Hit diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 5b062154f..2f8330c2d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -33,7 +33,7 @@ public struct Collider : IComponentData public ColliderHeader Header; public int Id => Header.Id; - public Entity Entity => Header.Entity; + public int ItemId => Header.ItemId; public ColliderType Type => Header.Type; public PhysicsMaterialData Material => Header.Material; public float Threshold => Header.Threshold; @@ -123,13 +123,22 @@ internal static unsafe float HitTest(ref Collider coll, ref CollisionEventData c } } } + + internal static float HitTest(ref BallData ball, in PlaneCollider coll, float dTime) + { + var collEvent = new CollisionEventData(); + var hitTime = coll.HitTest(ref collEvent, in ball, dTime); + ball.CollisionEvent = collEvent; + + return hitTime; + } /// /// Most colliders use the standard Collide3DWall routine, only overrides /// are cast and dispatched to their respective implementation. /// internal static unsafe void Collide(ref Collider coll, ref BallData ballData, - ref NativeQueue.ParallelWriter events, in Entity ballEntity, + ref NativeQueue.ParallelWriter events, in int ballId, in CollisionEventData collEvent, ref Random random) { fixed (Collider* collider = &coll) @@ -140,22 +149,22 @@ internal static unsafe void Collide(ref Collider coll, ref BallData ballData, ((CircleCollider*) collider)->Collide(ref ballData, in collEvent, ref random); break; case ColliderType.Line: - ((LineCollider*) collider)->Collide(ref ballData, ref events, in ballEntity, in collEvent, ref random); + ((LineCollider*) collider)->Collide(ref ballData, ref events, in ballId, in collEvent, ref random); break; case ColliderType.Line3D: - ((Line3DCollider*) collider)->Collide(ref ballData, ref events, in ballEntity, in collEvent, ref random); + ((Line3DCollider*) collider)->Collide(ref ballData, ref events, in ballId, in collEvent, ref random); break; case ColliderType.LineZ: - ((LineZCollider*) collider)->Collide(ref ballData, ref events, in ballEntity, in collEvent, ref random); + ((LineZCollider*) collider)->Collide(ref ballData, ref events, in ballId, in collEvent, ref random); break; case ColliderType.Plane: ((PlaneCollider*) collider)->Collide(ref ballData, in collEvent, ref random); break; case ColliderType.Point: - ((PointCollider*) collider)->Collide(ref ballData, ref events, in ballEntity, in collEvent, ref random); + ((PointCollider*) collider)->Collide(ref ballData, ref events, in ballId, in collEvent, ref random); break; case ColliderType.Triangle: - ((TriangleCollider*) collider)->Collide(ref ballData, ref events, in ballEntity, in collEvent, ref random); + ((TriangleCollider*) collider)->Collide(ref ballData, ref events, in ballId, in collEvent, ref random); break; default: @@ -164,7 +173,7 @@ internal static unsafe void Collide(ref Collider coll, ref BallData ballData, } } - internal static void FireHitEvent(ref BallData ball, ref NativeQueue.ParallelWriter events, in Entity ballEntity, in ColliderHeader collHeader) + internal static void FireHitEvent(ref BallData ball, ref NativeQueue.ParallelWriter events, in int ballId, in ColliderHeader collHeader) { if (collHeader.FireEvents/* && collHeader.IsEnabled*/) { // todo enabled @@ -180,7 +189,7 @@ internal static void FireHitEvent(ref BallData ball, ref NativeQueue. // must be a new place if only by a little if (distLs > normalDist) { - events.Enqueue(new EventData(EventId.HitEventsHit, collHeader.Entity, ballEntity, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, collHeader.ItemId, ballId, true)); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs index 2ce7013cf..c9375bb23 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs @@ -29,8 +29,8 @@ namespace VisualPinball.Unity public struct ColliderInfo { public int Id; + public int ItemId; public ItemType ItemType; - public Entity Entity; public PhysicsMaterialData Material; public float HitThreshold; public bool FireEvents; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs index 0c8f7a24a..2ded52709 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs @@ -73,7 +73,7 @@ public Line3DCollider(float3 v1, float3 v2, ColliderInfo info) : this() _zLow = math.min(trans1.z, trans2Z); _zHigh = math.max(trans1.z, trans2Z); - Bounds = new ColliderBounds(_header.Entity, _header.Id, new Aabb( + Bounds = new ColliderBounds(_header.ItemId, _header.Id, new Aabb( math.min(v1.x, v2.x), math.max(v1.x, v2.x), math.min(v1.y, v2.y), @@ -132,14 +132,14 @@ private static float HitTest(ref CollisionEventData collEvent, ref Line3DCollide #endregion public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, - in Entity ballEntity, in CollisionEventData collEvent, ref Random random) + in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); if (_header.FireEvents && dot >= _header.Threshold && _header.IsPrimitive) { // todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in ballEntity, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in _header); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index 3469616d9..15ff706aa 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -38,12 +38,12 @@ internal struct LineCollider : ICollider private float _length; private ItemType ItemType => _header.ItemType; - private Entity Entity => _header.Entity; + private int ItemId => _header.ItemId; public float V1y { set => V1.y = value; } public float V2y { set => V2.y = value; } - public ColliderBounds Bounds => new ColliderBounds(_header.Entity, _header.Id, new Aabb( + public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( math.min(V1.x, V2.x), math.max(V1.x, V2.x), math.min(V1.y, V2.y), @@ -171,7 +171,7 @@ public static float HitTestBasic(ref CollisionEventData collEvent, ref DynamicBu /*todo || !ball.m_vpVolObjs*/ // it's a trigger, so test: || math.abs(bnd) >= ball.Radius * 0.5f // not too close ... nor too far away - || inside == BallData.IsInsideOf(in insideOfs, coll.Entity)) // ...ball outside and hit set or ball inside and no hit set + || inside == BallData.IsInsideOf(in insideOfs, coll.ItemId)) // ...ball outside and hit set or ball inside and no hit set { return -1.0f; } @@ -230,13 +230,13 @@ public static float HitTestBasic(ref CollisionEventData collEvent, ref DynamicBu #region Collision public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, - in Entity ballEntity, in CollisionEventData collEvent, ref Random random) + in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); if (dot <= -_header.Threshold) { - Collider.FireHitEvent(ref ball, ref hitEvents, in ballEntity, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in _header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs index f03b7593f..925ebbf54 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs @@ -38,7 +38,7 @@ internal struct LineSlingshotCollider : ICollider private readonly float _force; - public ColliderBounds Bounds => new ColliderBounds(_header.Entity, _header.Id, new Aabb( + public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( math.min(V1.x, V2.x), math.max(V1.x, V2.x), math.min(V1.y, V2.y), @@ -98,7 +98,7 @@ private static float HitTest(ref CollisionEventData collEvent, ref LineSlingshot #region Collision - public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, in Entity ballEntity, in LineSlingshotData slingshotData, in CollisionEventData collEvent, ref Random random) + public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, in int ballId, in LineSlingshotData slingshotData, in CollisionEventData collEvent, ref Random random) { var hitNormal = collEvent.HitNormal; @@ -143,7 +143,7 @@ public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter // !! magic distance, must be a new place if only by a little if (distLs > 0.25f) { - events.Enqueue(new EventData(EventId.SurfaceEventsSlingshot, _header.Entity, ballEntity, true)); + events.Enqueue(new EventData(EventId.SurfaceEventsSlingshot, _header.ItemId, ballId, true)); // todo slingshot animation // m_slingshotanim.m_TimeReset = g_pplayer->m_time_msec + 100; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs index 20eb1afcf..ce0d9f1ac 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs @@ -34,7 +34,7 @@ internal struct LineZCollider : ICollider public float XyY { set => XY.y = value; } - public ColliderBounds Bounds => new ColliderBounds(_header.Entity, _header.Id, new Aabb ( + public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb ( XY.x, XY.x, XY.y, @@ -165,13 +165,13 @@ public static float HitTest(ref CollisionEventData collEvent, in LineZCollider c #region Collision public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, - in Entity ballEntity, in CollisionEventData collEvent, ref Random random) + in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); if (dot <= -_header.Threshold) { - Collider.FireHitEvent(ref ball, ref hitEvents, in ballEntity, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in _header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index 4af8b8561..909221448 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -30,7 +30,7 @@ internal struct PlaneCollider : ICollider private readonly float3 _normal; private readonly float _distance; - public ColliderBounds Bounds => new ColliderBounds(_header.Entity, _header.Id, new Aabb(float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue)); + public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb(float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue)); public PlaneCollider(float3 normal, float distance, ColliderInfo info) : this() { @@ -53,7 +53,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray new ColliderBounds(_header.Entity, _header.Id, new Aabb( + public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( P.x, P.x, P.y, @@ -141,13 +141,13 @@ public float HitTest(ref CollisionEventData collEvent, in BallData ball, float d #region Collision public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, - in Entity ballEntity, in CollisionEventData collEvent, ref Random random) + in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); if (dot <= -_header.Threshold) { - Collider.FireHitEvent(ref ball, ref hitEvents, in ballEntity, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in _header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs index ab63b4a37..586fe9fc1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs @@ -36,7 +36,7 @@ internal struct TriangleCollider : ICollider public float3 Normal() => _normal; - public ColliderBounds Bounds => new ColliderBounds(_header.Entity, _header.Id, new Aabb( + public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( math.min(Rgv0.x, math.min(Rgv1.x, Rgv2.x)), math.max(Rgv0.x, math.max(Rgv1.x, Rgv2.x)), math.min(Rgv0.y, math.min(Rgv1.y, Rgv2.y)), @@ -155,7 +155,7 @@ public float HitTest(ref CollisionEventData collEvent, in DynamicBuffer 0; } @@ -178,14 +178,14 @@ public float HitTest(ref CollisionEventData collEvent, in DynamicBuffer.ParallelWriter hitEvents, - in Entity ballEntity, in CollisionEventData collEvent, ref Random random) + in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = -math.dot(collEvent.HitNormal, ball.Velocity); BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in _normal, ref random); if (_header.FireEvents && dot >= _header.Threshold && _header.IsPrimitive) { // todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in ballEntity, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in _header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs index 27b9fc4c1..709ac06f8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs @@ -21,17 +21,17 @@ namespace VisualPinball.Unity { public struct ColliderBounds { - public Entity ColliderEntity; + public int ItemId; public int ColliderId; public Aabb Aabb; - public ColliderBounds(Entity colliderEntity, int colliderId, Aabb aabb) + public ColliderBounds(int itemId, int colliderId, Aabb aabb) { - if (colliderEntity == Entity.Null) { - throw new ArgumentException("Entity must not be null."); + if (itemId == 0) { + throw new ArgumentException("Item ID must not be null."); } - ColliderEntity = colliderEntity; + ItemId = itemId; ColliderId = colliderId; Aabb = aabb; } @@ -40,7 +40,7 @@ public ColliderBounds(Entity colliderEntity, int colliderId, Aabb aabb) public override string ToString() { - return $"{Aabb.ToString()} ({ColliderId}:{ColliderEntity})"; + return $"{Aabb.ToString()} ({ItemId}:{ColliderId})"; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs index 49a127b5e..dbd079b99 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs @@ -30,7 +30,7 @@ public struct ColliderHeader public ColliderType Type; public ItemType ItemType; public int Id; - public Entity Entity; + public int ItemId; public PhysicsMaterialData Material; public float Threshold; @@ -54,13 +54,13 @@ public struct ColliderHeader public void Init(ColliderInfo info, ColliderType colliderType) { - if (info.Entity == Entity.Null) { + if (info.ItemId == 0) { throw new InvalidOperationException("Entity of " + info.ItemType + " " + colliderType + " not set!"); } Type = colliderType; ItemType = info.ItemType; Id = info.Id; - Entity = info.Entity; + ItemId = info.ItemId; Material = info.Material; Threshold = info.HitThreshold; FireEvents = info.FireEvents; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactBufferElement.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactBufferElement.cs index e1e1992ee..50e2d19ad 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactBufferElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactBufferElement.cs @@ -22,11 +22,11 @@ namespace VisualPinball.Unity internal struct ContactBufferElement : IBufferElementData { public CollisionEventData CollEvent; - public Entity BallEntity; + public int BallId; - public ContactBufferElement(Entity ballEntity, CollisionEventData collEvent) + public ContactBufferElement(int ballId, CollisionEventData collEvent) { - BallEntity = ballEntity; + BallId = ballId; CollEvent = collEvent; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs index 6655bbce4..27bd36f4d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs @@ -74,7 +74,7 @@ protected override void OnUpdate() var contact = contacts[i]; ref var collEvent = ref contact.CollEvent; - var ball = ballsLookup[contact.BallEntity]; + var ball = ballsLookup[Entity.Null]; // fixme jobs ballsLookup[contact.BallId]; if (collEvent.ColliderId > -1) { // collide with static collider ref var coll = ref colliders[collEvent.ColliderId].Value; @@ -84,13 +84,13 @@ protected override void OnUpdate() // flipper contact updates movement data if (coll.Type == ColliderType.Flipper) { - var flipperMovementData = GetComponent(coll.Entity); - var flipperMaterialData = GetComponent(coll.Entity); - var flipperVelocityData = GetComponent(coll.Entity); + var flipperMovementData = GetComponent(coll.ItemId); + var flipperMaterialData = GetComponent(coll.ItemId); + var flipperVelocityData = GetComponent(coll.ItemId); ((FlipperCollider*) collider)->Contact( ref ball, ref flipperMovementData, in collEvent, in flipperMaterialData, in flipperVelocityData, hitTime, in gravity); - SetComponent(coll.Entity, flipperMovementData); + SetComponent(coll.ItemId, flipperMovementData); } else { VisualPinball.Unity.Collider.Contact(ref coll, ref ball, in collEvent, hitTime, in gravity); @@ -103,7 +103,7 @@ protected override void OnUpdate() BallCollider.HandleStaticContact(ref ball, in collEvent, 0.3f, hitTime, in gravity); } - ballsLookup[contact.BallEntity] = ball; + ballsLookup[Entity.Null] = ball; // fixme jobs [contact.BallId] = ball; } marker.End(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs index d1731c915..935f81aee 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs @@ -66,7 +66,7 @@ protected override void OnUpdate() newCollEvent.SetCollider(collBallEntity); newCollEvent.HitTime = newTime; if (newCollEvent.IsContact) { - contacts.Add(new ContactBufferElement(ballEntity, newCollEvent)); + contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); } else { // if (validhit) collEvent = newCollEvent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs index 8e2c40fec..01102fce8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs @@ -40,7 +40,7 @@ public static void Create(BlobBuilder builder, ref BlobArray> var c = colliders[i].Value; var bounds = colliders[i].Value.Bounds(); //Debug.Log("Adding aabb " + aabb + " (" + colliders[i].Value.Type + ")"); - if (bounds.ColliderEntity == Entity.Null) { + if (bounds.ItemId == 0) { throw new InvalidOperationException($"Entity of {bounds} must be set ({colliders[i].Value.ItemType})."); } if (bounds.ColliderId < 0) { @@ -174,7 +174,7 @@ private static void CopyBounds(BlobBuilder builder, IReadOnlyList ite for (var i = 0; i < _bounds.Length; i++) { ref var bounds = ref _bounds[i].Value; - if (itemsColliding[bounds.ColliderEntity] && bounds.Aabb.IntersectRect(ballAabb) && bounds.Aabb.IntersectSphere(ball.Position, collisionRadiusSqr)) { - matchedColliderIds.Add(new OverlappingStaticColliderBufferElement { Value = bounds.ColliderId }); - } + // if (itemsColliding[bounds.ColliderEntity] && bounds.Aabb.IntersectRect(ballAabb) && bounds.Aabb.IntersectSphere(ball.Position, collisionRadiusSqr)) { + // matchedColliderIds.Add(new OverlappingStaticColliderBufferElement { Value = bounds.ColliderId }); + // } } if (!_isLeaf) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs index 649ddfe6f..7e9f174ae 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs @@ -47,15 +47,16 @@ public static void Create(EntityManager entityManager, out NativeHashMap(); - var (playfieldCollider, glassCollider) = player.PlayfieldApi.CreateColliders(); + var (playfieldCollider, glassCollider) = player.PlayfieldApi.CreateColliders(0); itemsColliding = new NativeHashMap(itemApis.Length, Allocator.Persistent); foreach (var itemApi in itemApis) { - PerfMarkerCreateColliders.Begin(); - if (itemApi.ColliderEntity != Entity.Null) { - itemsColliding.Add(itemApi.ColliderEntity, itemApi.IsColliderEnabled); - } - itemApi.CreateColliders(colliderList, 0); - PerfMarkerCreateColliders.End(); + // fixme job + // PerfMarkerCreateColliders.Begin(); + // if (itemApi.ColliderEntity != Entity.Null) { + // itemsColliding.Add(itemApi.ColliderEntity, itemApi.IsColliderEnabled); + // } + // itemApi.CreateColliders(colliderList, 0); + // PerfMarkerCreateColliders.End(); } PerfMarkerGenerateColliders.End(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs index 39f798453..c62af8203 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs @@ -74,6 +74,7 @@ protected override void OnUpdate() .ForEach((Entity ballEntity, ref BallData ballData, ref CollisionEventData collEvent, ref DynamicBuffer insideOfs) => { + var ballId = 0; // find balls with hit objects and minimum time if (collEvent.ColliderId < 0 || collEvent.HitTime > hitTime) { return; @@ -96,95 +97,95 @@ protected override void OnUpdate() switch (coll.Type) { case ColliderType.Bumper: { - var bumperStaticData = GetComponent(coll.Entity); - var animateRing = HasComponent(coll.Entity); - var animateSkirt = HasComponent(coll.Entity); - var ringData = animateRing ? GetComponent(coll.Entity) : default; - var skirtData = animateSkirt ? GetComponent(coll.Entity): default; + var bumperStaticData = GetComponent(coll.ItemId); + var animateRing = HasComponent(coll.ItemId); + var animateSkirt = HasComponent(coll.ItemId); + var ringData = animateRing ? GetComponent(coll.ItemId) : default; + var skirtData = animateSkirt ? GetComponent(coll.ItemId): default; BumperCollider.Collide(ref ballData, ref events, ref collEvent, ref ringData, ref skirtData, - in ballEntity, in coll, bumperStaticData, ref random); + in ballId, in coll, bumperStaticData, ref random); if (animateRing) { - SetComponent(coll.Entity, ringData); + SetComponent(coll.ItemId, ringData); } if (animateSkirt) { - SetComponent(coll.Entity, skirtData); + SetComponent(coll.ItemId, skirtData); } break; } case ColliderType.Flipper: { - var flipperVelocityData = GetComponent(coll.Entity); - var flipperMovementData = GetComponent(coll.Entity); - var flipperMaterialData = GetComponent(coll.Entity); - var flipperHitData = GetComponent(coll.Entity); - var flipperTricksData = GetComponent(coll.Entity); + var flipperVelocityData = GetComponent(coll.ItemId); + var flipperMovementData = GetComponent(coll.ItemId); + var flipperMaterialData = GetComponent(coll.ItemId); + var flipperHitData = GetComponent(coll.ItemId); + var flipperTricksData = GetComponent(coll.ItemId); // do liveCatch - check before collision FlipperCollider.LiveCatch( ref ballData, ref collEvent, ref flipperTricksData, in flipperMaterialData, timeMsec ); ((FlipperCollider*)collider)->Collide( ref ballData, ref collEvent, ref flipperMovementData, ref events, - in ballEntity, in flipperTricksData,in flipperMaterialData, in flipperVelocityData, in flipperHitData, timeMsec + in ballId, in flipperTricksData,in flipperMaterialData, in flipperVelocityData, in flipperHitData, timeMsec ); - SetComponent(coll.Entity, flipperMovementData); + SetComponent(coll.ItemId, flipperMovementData); break; } case ColliderType.Gate: { - var gateStaticData = GetComponent(coll.Entity); - var gateMovementData = GetComponent(coll.Entity); + var gateStaticData = GetComponent(coll.ItemId); + var gateMovementData = GetComponent(coll.ItemId); GateCollider.Collide( ref ballData, ref collEvent, ref gateMovementData, ref events, - in ballEntity, in coll, in gateStaticData + in ballId, in coll, in gateStaticData ); - SetComponent(coll.Entity, gateMovementData); + SetComponent(coll.ItemId, gateMovementData); break; } case ColliderType.LineSlingShot: { - var slingshotData = GetComponent(coll.Entity); + var slingshotData = GetComponent(coll.ItemId); ((LineSlingshotCollider*)collider)->Collide( ref ballData, ref events, - in ballEntity, in slingshotData, in collEvent, ref random); + in ballId, in slingshotData, in collEvent, ref random); break; } case ColliderType.Plunger: { - var plungerMovementData = GetComponent(coll.Entity); - var plungerStaticData = GetComponent(coll.Entity); + var plungerMovementData = GetComponent(coll.ItemId); + var plungerStaticData = GetComponent(coll.ItemId); PlungerCollider.Collide( ref ballData, ref collEvent, ref plungerMovementData, in plungerStaticData, ref random); - SetComponent(coll.Entity, plungerMovementData); + SetComponent(coll.ItemId, plungerMovementData); break; } case ColliderType.Spinner: { - var spinnerStaticData = GetComponent(coll.Entity); - var spinnerMovementData = GetComponent(coll.Entity); + var spinnerStaticData = GetComponent(coll.ItemId); + var spinnerMovementData = GetComponent(coll.ItemId); SpinnerCollider.Collide( in ballData, ref collEvent, ref spinnerMovementData, in spinnerStaticData ); - SetComponent(coll.Entity, spinnerMovementData); + SetComponent(coll.ItemId, spinnerMovementData); break; } case ColliderType.TriggerCircle: case ColliderType.TriggerLine: { - var triggerAnimationData = HasComponent(coll.Entity) - ? GetComponent(coll.Entity) + var triggerAnimationData = HasComponent(coll.ItemId) + ? GetComponent(coll.ItemId) : new TriggerAnimationData(); TriggerCollider.Collide( ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, - in ballEntity, in coll + in ballId, in coll ); - if (HasComponent(coll.Entity)) { + if (HasComponent(coll.ItemId)) { if (triggerAnimationData.UnHitEvent) { - var flipperCorrectionData = GetComponent(coll.Entity); + var flipperCorrectionData = GetComponent(coll.ItemId); ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); @@ -195,22 +196,22 @@ in spinnerStaticData } } else { - SetComponent(coll.Entity, triggerAnimationData); + SetComponent(coll.ItemId, triggerAnimationData); } break; } case ColliderType.KickerCircle: { - var kickerCollisionData = GetComponent(coll.Entity); - var kickerStaticData = GetComponent(coll.Entity); + var kickerCollisionData = GetComponent(coll.ItemId); + var kickerStaticData = GetComponent(coll.ItemId); // ReSharper disable once ConditionIsAlwaysTrueOrFalse var legacyMode = KickerCollider.ForceLegacyMode || kickerStaticData.LegacyMode; // ReSharper disable once ConditionIsAlwaysTrueOrFalse - var kickerMeshData = !legacyMode ? GetComponent(coll.Entity) : default; + var kickerMeshData = !legacyMode ? GetComponent(coll.ItemId) : default; KickerCollider.Collide(ref ballData, ref events, ref insideOfs, ref kickerCollisionData, - in kickerStaticData, in kickerMeshData, in collEvent, coll.Entity, in ballEntity + in kickerStaticData, in kickerMeshData, in collEvent, coll.ItemId, in ballId ); - SetComponent(coll.Entity, kickerCollisionData); + SetComponent(coll.ItemId, kickerCollisionData); break; } @@ -229,35 +230,35 @@ in spinnerStaticData ? ((TriangleCollider*) collider)->Normal() : collEvent.HitNormal; - if (HasComponent(coll.Entity)) { - var dropTargetAnimationData = GetComponent(coll.Entity); + if (HasComponent(coll.ItemId)) { + var dropTargetAnimationData = GetComponent(coll.ItemId); TargetCollider.DropTargetCollide(ref ballData, ref events, ref dropTargetAnimationData, - in normal, in ballEntity, in collEvent, in coll, ref random); - SetComponent(coll.Entity, dropTargetAnimationData); + in normal, in ballId, in collEvent, in coll, ref random); + SetComponent(coll.ItemId, dropTargetAnimationData); } - if (HasComponent(coll.Entity)) { - var hitTargetAnimationData = GetComponent(coll.Entity); + if (HasComponent(coll.ItemId)) { + var hitTargetAnimationData = GetComponent(coll.ItemId); TargetCollider.HitTargetCollide(ref ballData, ref events, ref hitTargetAnimationData, - in normal, in ballEntity, in collEvent, in coll, ref random); - SetComponent(coll.Entity, hitTargetAnimationData); + in normal, in ballId, in collEvent, in coll, ref random); + SetComponent(coll.ItemId, hitTargetAnimationData); } // trigger } else if (coll.Header.ItemType == ItemType.Trigger) { - var triggerAnimationData = HasComponent(coll.Entity) - ? GetComponent(coll.Entity) + var triggerAnimationData = HasComponent(coll.ItemId) + ? GetComponent(coll.ItemId) : new TriggerAnimationData(); TriggerCollider.Collide( ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, - in ballEntity, in coll + in ballId, in coll ); - if (HasComponent(coll.Entity)) { + if (HasComponent(coll.ItemId)) { if (triggerAnimationData.UnHitEvent) { - var flipperCorrectionData = GetComponent(coll.Entity); + var flipperCorrectionData = GetComponent(coll.ItemId); ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); @@ -268,11 +269,11 @@ in spinnerStaticData } } else { - SetComponent(coll.Entity, triggerAnimationData); + SetComponent(coll.ItemId, triggerAnimationData); } } else { - Collider.Collide(ref coll, ref ballData, ref events, in ballEntity, in collEvent, ref random); + Collider.Collide(ref coll, ref ballData, ref events, in ballId, in collEvent, ref random); } break; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs index 573bfa4d4..57d788565 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs @@ -72,10 +72,10 @@ protected override void OnUpdate() // check playfield and glass first if (collideAgainstPlayfieldPlane) { ref var playfieldCollider = ref colliders[collData.Value.Value.PlayfieldColliderId].Value; - HitTest(ref playfieldCollider, ref collEvent, ref contacts, ref insideOfs, in ballEntity, in ballData); + HitTest(ref playfieldCollider, ref collEvent, ref contacts, ref insideOfs, in ballData.Id, in ballData); } ref var glassCollider = ref colliders[collData.Value.Value.GlassColliderId].Value; - HitTest(ref glassCollider, ref collEvent, ref contacts, ref insideOfs, in ballEntity, in ballData); + HitTest(ref glassCollider, ref collEvent, ref contacts, ref insideOfs, in ballData.Id, in ballData); var traversalOrder = false; //random.NextBool(); var start = traversalOrder ? 0 : colliderIds.Length - 1; @@ -98,37 +98,37 @@ protected override void OnUpdate() break; case ColliderType.Flipper: - if (HasComponent(coll.Entity) && - HasComponent(coll.Entity) && - HasComponent(coll.Entity)) + if (HasComponent(coll.ItemId) && + HasComponent(coll.ItemId) && + HasComponent(coll.ItemId)) { - var flipperHitData = GetComponent(coll.Entity); - var flipperMovementData = GetComponent(coll.Entity); - var flipperMaterialData = GetComponent(coll.Entity); - var flipperTricksData = GetComponent(coll.Entity); + var flipperHitData = GetComponent(coll.ItemId); + var flipperMovementData = GetComponent(coll.ItemId); + var flipperMaterialData = GetComponent(coll.ItemId); + var flipperTricksData = GetComponent(coll.ItemId); newTime = ((FlipperCollider*)collider)->HitTest( ref newCollEvent, ref insideOfs, ref flipperHitData, in flipperMovementData, in flipperTricksData, in flipperMaterialData, in ballData, collEvent.HitTime ); - SetComponent(coll.Entity, flipperHitData); + SetComponent(coll.ItemId, flipperHitData); } break; case ColliderType.Plunger: - if (HasComponent(coll.Entity) && - HasComponent(coll.Entity) && - HasComponent(coll.Entity)) + if (HasComponent(coll.ItemId) && + HasComponent(coll.ItemId) && + HasComponent(coll.ItemId)) { - var plungerColliderData = GetComponent(coll.Entity); - var plungerStaticData = GetComponent(coll.Entity); - var plungerMovementData = GetComponent(coll.Entity); + var plungerColliderData = GetComponent(coll.ItemId); + var plungerStaticData = GetComponent(coll.ItemId); + var plungerMovementData = GetComponent(coll.ItemId); newTime = ((PlungerCollider*)collider)->HitTest( ref newCollEvent, ref insideOfs, ref plungerMovementData, in plungerColliderData, in plungerStaticData, in ballData, collEvent.HitTime ); - SetComponent(coll.Entity, plungerMovementData); + SetComponent(coll.ItemId, plungerMovementData); } break; case ColliderType.Line: @@ -140,8 +140,8 @@ protected override void OnUpdate() case ColliderType.Triangle: // hit target if (coll.Header.ItemType == ItemType.HitTarget) { - if (HasComponent(coll.Entity)) { - var dropTargetAnimationData = GetComponent(coll.Entity); + if (HasComponent(coll.ItemId)) { + var dropTargetAnimationData = GetComponent(coll.ItemId); if (dropTargetAnimationData.IsDropped || dropTargetAnimationData.MoveAnimation) { // QUICKFIX so that DT is not triggered twice saveCollision = false; } @@ -149,7 +149,7 @@ protected override void OnUpdate() newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); } } - if (HasComponent(coll.Entity)) { + if (HasComponent(coll.ItemId)) { newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); } } @@ -164,7 +164,7 @@ protected override void OnUpdate() } } if (saveCollision) { - SaveCollisions(ref collEvent, ref newCollEvent, ref contacts, in ballEntity, in coll, newTime); + SaveCollisions(ref collEvent, ref newCollEvent, ref contacts, in ballData.Id, in coll, newTime); } } @@ -180,7 +180,7 @@ protected override void OnUpdate() private static void HitTest(ref Collider coll, ref CollisionEventData collEvent, ref NativeList contacts, ref DynamicBuffer insideOfs, - in Entity ballEntity, in BallData ballData) { + in int ballId, in BallData ballData) { // todo // if (collider.obj && collider.obj.abortHitTest && collider.obj.abortHitTest()) { @@ -190,11 +190,11 @@ private static void HitTest(ref Collider coll, ref CollisionEventData collEvent, var newCollEvent = new CollisionEventData(); var newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); - SaveCollisions(ref collEvent, ref newCollEvent, ref contacts, in ballEntity, in coll, newTime); + SaveCollisions(ref collEvent, ref newCollEvent, ref contacts, in ballId, in coll, newTime); } private static void SaveCollisions(ref CollisionEventData collEvent, ref CollisionEventData newCollEvent, - ref NativeList contacts, in Entity ballEntity, in Collider coll, float newTime) + ref NativeList contacts, in int ballId, in Collider coll, float newTime) { var validHit = newTime >= 0f && !Math.Sign(newTime) && newTime <= collEvent.HitTime; @@ -202,7 +202,7 @@ private static void SaveCollisions(ref CollisionEventData collEvent, ref Collisi newCollEvent.SetCollider(coll.Id); newCollEvent.HitTime = newTime; if (newCollEvent.IsContact) { - contacts.Add(new ContactBufferElement(ballEntity, newCollEvent)); + contacts.Add(new ContactBufferElement(ballId, newCollEvent)); } else { // if (validhit) collEvent = newCollEvent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs index 339434703..e257adc5e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs @@ -38,9 +38,9 @@ public interface IDebugUI : IEngine /// /// Called when a flipper has been converted to an entity. /// - /// Flipper entity + /// Flipper entity /// Name of the flipper - void OnRegisterFlipper(Entity entity, string name); + void OnRegisterFlipper(int itemId, string name); /// /// Called when a new ball has been created. diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs index a654380da..7de413e4b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs @@ -65,10 +65,10 @@ public void Init(TableComponent tableComponent, BallManager ballManager) } public void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, - in float3 localVel, in float scale, in float mass, in float radius, in Entity kickerRef) + in float3 localVel, in float scale, in float mass, in float radius, in int kickerId) { _ballManager.CreateEntity(ballGo, id, in worldPos, in localPos, in localVel,scale * radius * 2, - in mass, in radius, in kickerRef); + in mass, in radius, in kickerId); } public void BallManualRoll(in Entity entity, in float3 targetWorldPosition) @@ -96,22 +96,24 @@ public void BallManualRoll(in Entity entity, in float3 targetWorldPosition) } } - public void FlipperRotateToEnd(in Entity entity) + public void FlipperRotateToEnd(in int itemId) { - var mData = _entityManager.GetComponentData(entity); - mData.EnableRotateEvent = 1; - mData.StartRotateToEndTime = _visualPinballSimulationSystemGroup.TimeMsec; - mData.AngleAtRotateToEnd = mData.Angle; - _entityManager.SetComponentData(entity, mData); - _entityManager.SetComponentData(entity, new SolenoidStateData { Value = true }); + // fixme job + // var mData = _entityManager.GetComponentData(entity); + // mData.EnableRotateEvent = 1; + // mData.StartRotateToEndTime = _visualPinballSimulationSystemGroup.TimeMsec; + // mData.AngleAtRotateToEnd = mData.Angle; + // _entityManager.SetComponentData(entity, mData); + // _entityManager.SetComponentData(entity, new SolenoidStateData { Value = true }); } - public void FlipperRotateToStart(in Entity entity) + public void FlipperRotateToStart(in int itemId) { - var mData = _entityManager.GetComponentData(entity); - mData.EnableRotateEvent = -1; - _entityManager.SetComponentData(entity, mData); - _entityManager.SetComponentData(entity, new SolenoidStateData { Value = false }); + // fixme job + // var mData = _entityManager.GetComponentData(entity); + // mData.EnableRotateEvent = -1; + // _entityManager.SetComponentData(entity, mData); + // _entityManager.SetComponentData(entity, new SolenoidStateData { Value = false }); } public DebugFlipperState[] FlipperGetDebugStates() diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs index ae074efd3..6fda9c46b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs @@ -50,7 +50,7 @@ public interface IPhysicsEngine : IEngine /// Radius in local space /// If created within a kicker, this is the kicker entity void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, in float3 localVel, - in float scale, in float mass, in float radius, in Entity kickerRef); + in float scale, in float mass, in float radius, in int kickerId); /// /// Rolls the ball manually to a position on the playfield. @@ -62,14 +62,14 @@ void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPo /// /// Rotate the flipper "up" (button pressed) /// - /// - void FlipperRotateToEnd(in Entity entity); + /// + void FlipperRotateToEnd(in int itemId); /// /// Rotate the flipper "down" (button released) /// - /// - void FlipperRotateToStart(in Entity entity); + /// + void FlipperRotateToStart(in int itemId); /// /// Returns a simplified version of all flipper states for the diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs index 5da918989..79cf5e8c8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs @@ -26,42 +26,42 @@ namespace VisualPinball.Unity public readonly struct EventData { public readonly EventId eventId; - public readonly Entity ItemEntity; - public readonly Entity BallEntity; + public readonly int ItemId; + public readonly int BallId; public readonly float FloatParam; public readonly bool GroupEvent; - public EventData(EventId eventId, Entity itemEntity, Entity ballEntity, bool groupEvent = false) : this() + public EventData(EventId eventId, int itemId, int ballId, bool groupEvent = false) : this() { this.eventId = eventId; - ItemEntity = itemEntity; - BallEntity = ballEntity; + ItemId = itemId; + BallId = ballId; GroupEvent = groupEvent; } - public EventData(EventId eventId, Entity itemEntity, Entity ballEntity, float floatParam, bool groupEvent = false) : this() + public EventData(EventId eventId, int itemId, int ballId, float floatParam, bool groupEvent = false) : this() { this.eventId = eventId; - ItemEntity = itemEntity; - BallEntity = ballEntity; + ItemId = itemId; + BallId = ballId; FloatParam = floatParam; GroupEvent = groupEvent; } - public EventData(EventId eventId, Entity itemEntity, bool groupEvent = false) : this() + public EventData(EventId eventId, int itemId, bool groupEvent = false) : this() { this.eventId = eventId; - ItemEntity = itemEntity; - BallEntity = Entity.Null; + ItemId = itemId; + BallId = 0; GroupEvent = groupEvent; } - public EventData(EventId eventId, Entity itemEntity, float floatParam, bool groupEvent = false) : this() + public EventData(EventId eventId, int itemId, float floatParam, bool groupEvent = false) : this() { this.eventId = eventId; - ItemEntity = itemEntity; - BallEntity = Entity.Null; + ItemId = itemId; + BallId = 0; FloatParam = floatParam; GroupEvent = groupEvent; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs index 6afbe306e..72b778f45 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs @@ -14,6 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; +using Unity.Collections; using Unity.Entities; using Unity.Mathematics; @@ -60,6 +62,8 @@ internal struct BallData : IComponentData public float3 OldVelocity; + public CollisionEventData CollisionEvent; + public Aabb Aabb { get { var vl = math.length(Velocity) + Radius + 0.05f; // 0.05f = paranoia @@ -147,30 +151,30 @@ the angular velocity used here is not the angular velocity that the ball has (wh */ } - public static void SetOutsideOf(ref DynamicBuffer insideOfs, in Entity entity) + public static void SetOutsideOf(ref DynamicBuffer insideOfs, in int itemId) { for (var i = 0; i < insideOfs.Length; i++) { - if (insideOfs[i].Value == entity) { + if (insideOfs[i].Value == itemId) { insideOfs.RemoveAt(i); return; } } } - public static void SetInsideOf(ref DynamicBuffer insideOfs, Entity entity) + public static void SetInsideOf(ref DynamicBuffer insideOfs, int itemId) { - insideOfs.Add(new BallInsideOfBufferElement { Value = entity }); + insideOfs.Add(new BallInsideOfBufferElement { Value = itemId }); } - public static bool IsOutsideOf(in DynamicBuffer insideOfs, in Entity entity) + public static bool IsOutsideOf(in DynamicBuffer insideOfs, in int itemId) { - return !IsInsideOf(in insideOfs, in entity); + return !IsInsideOf(in insideOfs, in itemId); } - public static bool IsInsideOf(in DynamicBuffer insideOfs, in Entity entity) + public static bool IsInsideOf(in DynamicBuffer insideOfs, in int itemId) { for (var i = 0; i < insideOfs.Length; i++) { - if (insideOfs[i].Value == entity) { + if (insideOfs[i].Value == itemId) { return true; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs index f7bf14f30..8bdf41e50 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs @@ -25,6 +25,6 @@ namespace VisualPinball.Unity [InternalBufferCapacity(0)] internal struct BallInsideOfBufferElement : IBufferElementData { - public Entity Value; + public int Value; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index 8bf020e42..ce38ec817 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -49,10 +49,10 @@ public BallManager(Player player) public void CreateBall(IBallCreationPosition ballCreator, float radius = 25f, float mass = 1f) { - CreateBall(ballCreator, radius, mass, Entity.Null); + CreateBall(ballCreator, radius, mass, 0); } - public void CreateBall(IBallCreationPosition ballCreator, float radius, float mass, in Entity kickerRef) + public void CreateBall(IBallCreationPosition ballCreator, float radius, float mass, int kickerId) { var localPos = ballCreator.GetBallCreationPosition().ToUnityFloat3(); var localVel = ballCreator.GetBallCreationVelocity().ToUnityFloat3(); @@ -77,11 +77,11 @@ public void CreateBall(IBallCreationPosition ballCreator, float radius, float ma // create ball entity EngineProvider .Get() - .BallCreate(ballGo, ballId, worldPos, localPos, localVel, scale, mass, radius, in kickerRef); + .BallCreate(ballGo, ballId, worldPos, localPos, localVel, scale, mass, radius, kickerId); } public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, in float3 localVel, in float scale, - in float mass, in float radius, in Entity kickerEntity) + in float mass, in float radius, in int kickerId) { // Efficiently instantiate a bunch of entities from the already converted entity prefab var entity = EntityManager.CreateEntity( @@ -97,7 +97,7 @@ public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float EntityManager.SetName(entity, $"Ball{id}"); #endif - _player.Balls[entity] = ballGo; + _player.Balls[kickerId] = ballGo; var world = World.DefaultGameObjectInjectionWorld; var ecbs = world.GetOrCreateSystemManaged(); @@ -109,7 +109,7 @@ public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float ecb.AddComponent(entity, new BallData { Id = id, - IsFrozen = kickerEntity != Entity.Null, + IsFrozen = kickerId != 0, Position = localPos, Radius = radius, Mass = mass, @@ -136,16 +136,17 @@ public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float } // handle inside-kicker creation - if (kickerEntity != Entity.Null) { - var kickerData = EntityManager.GetComponentData(kickerEntity); - if (!kickerData.FallThrough) { - var kickerCollData = EntityManager.GetComponentData(kickerEntity); - var inside = ecb.AddBuffer(entity); - BallData.SetInsideOf(ref inside, kickerEntity); - kickerCollData.BallEntity = entity; - kickerCollData.LastCapturedBallEntity = entity; - ecb.SetComponent(kickerEntity, kickerCollData); - } + if (kickerId != 0) { + // fixme job + // var kickerData = EntityManager.GetComponentData(kickerEntity); + // if (!kickerData.FallThrough) { + // var kickerCollData = EntityManager.GetComponentData(kickerEntity); + // var inside = ecb.AddBuffer(entity); + // BallData.SetInsideOf(ref inside, kickerEntity); + // kickerCollData.BallId = entity; + // kickerCollData.LastCapturedBallId = entity; + // ecb.SetComponent(kickerEntity, kickerCollData); + // } } NumBalls++; @@ -153,22 +154,23 @@ public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float _player.BallCreated(entity, ballGo); } - public void DestroyEntity(Entity ballEntity) + public void DestroyEntity(int ballId) { - var ballGo = _player.Balls[ballEntity]; - _player.BallDestroyed(ballEntity, ballGo); - - // destroy game object - Object.DestroyImmediate(ballGo); - _player.Balls.Remove(ballEntity); - - // destroy entity - World.DefaultGameObjectInjectionWorld - .GetOrCreateSystemManaged() - .CreateCommandBuffer() - .DestroyEntity(ballEntity); - - NumBalls--; + // fixme job + // var ballGo = _player.Balls[ballEntity]; + // _player.BallDestroyed(ballEntity, ballGo); + // + // // destroy game object + // Object.DestroyImmediate(ballGo); + // _player.Balls.Remove(ballEntity); + // + // // destroy entity + // World.DefaultGameObjectInjectionWorld + // .GetOrCreateSystemManaged() + // .CreateCommandBuffer() + // .DestroyEntity(ballEntity); + // + // NumBalls--; } /// diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs index a90541859..3d6008418 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs @@ -50,43 +50,44 @@ protected override void OnUpdate() { var ltw = _baseTransform; var marker = PerfMarker; - Entities.WithoutBurst().WithName("BallMovementJob").ForEach((Entity entity, in BallData ball) => { - - marker.Begin(); - - if (!_player.Balls.ContainsKey(entity)) { - marker.End(); - return; - } - - // calculate/adapt height of ball - var zHeight = !ball.IsFrozen ? ball.Position.z : ball.Position.z - ball.Radius; - var ballTransform = _player.Balls[entity].transform; - ballTransform.localPosition = VisualPinball.Unity.Physics.TranslateToWorld(ball.Position.x, ball.Position.y, zHeight); - - var or = ball.BallOrientationForUnity; - - var VPX = new Vector3(or.c0.x, or.c1.x, or.c2.x); - var VPY = new Vector3(or.c0.y, or.c1.y, or.c2.y); - var VPZ = new Vector3(or.c0.z, or.c1.z, or.c2.z); - - // Debug.Log("c0: (" + or.c0.x + ", " + or.c0.y + ", " + or.c0.z + ")"); - // Debug.Log("c1: (" + or.c1.x + ", " + or.c1.y + ", " + or.c1.z + ")"); - // Debug.Log("c2: (" + or.c2.x + ", " + or.c2.y + ", " + or.c2.z + ")"); - - // for security reasons, so that we don't get NaN, NaN, NaN, NaN erroro, when vectors are not fully orthonormalized because of skewMatrix operation - Vector3.OrthoNormalize(ref VPZ, ref VPY, ref VPX); - - Quaternion q = Quaternion.LookRotation(VPZ, VPY); - - // flip Z axis - q = FlipZAxis(q); - - ballTransform.localRotation = q.RotateToWorld(); - - marker.End(); - - }).Run(); + // fixme job + // Entities.WithoutBurst().WithName("BallMovementJob").ForEach((Entity entity, in BallData ball) => { + // + // marker.Begin(); + // + // if (!_player.Balls.ContainsKey(entity)) { + // marker.End(); + // return; + // } + // + // // calculate/adapt height of ball + // var zHeight = !ball.IsFrozen ? ball.Position.z : ball.Position.z - ball.Radius; + // var ballTransform = _player.Balls[entity].transform; + // ballTransform.localPosition = VisualPinball.Unity.Physics.TranslateToWorld(ball.Position.x, ball.Position.y, zHeight); + // + // var or = ball.BallOrientationForUnity; + // + // var VPX = new Vector3(or.c0.x, or.c1.x, or.c2.x); + // var VPY = new Vector3(or.c0.y, or.c1.y, or.c2.y); + // var VPZ = new Vector3(or.c0.z, or.c1.z, or.c2.z); + // + // // Debug.Log("c0: (" + or.c0.x + ", " + or.c0.y + ", " + or.c0.z + ")"); + // // Debug.Log("c1: (" + or.c1.x + ", " + or.c1.y + ", " + or.c1.z + ")"); + // // Debug.Log("c2: (" + or.c2.x + ", " + or.c2.y + ", " + or.c2.z + ")"); + // + // // for security reasons, so that we don't get NaN, NaN, NaN, NaN erroro, when vectors are not fully orthonormalized because of skewMatrix operation + // Vector3.OrthoNormalize(ref VPZ, ref VPY, ref VPX); + // + // Quaternion q = Quaternion.LookRotation(VPZ, VPY); + // + // // flip Z axis + // q = FlipZAxis(q); + // + // ballTransform.localRotation = q.RotateToWorld(); + // + // marker.End(); + // + // }).Run(); static Quaternion FlipZAxis(Quaternion q) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs index 496e4441c..cb272b4bf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs @@ -40,8 +40,7 @@ public class BumperApi : CollidableApi public event EventHandler Switch; - public BumperApi(GameObject go, Entity entity, Player player) - : base(go, entity, player) + public BumperApi(GameObject go, Player player) : base(go, player) { } @@ -58,11 +57,12 @@ public BumperApi(GameObject go, Entity entity, Player player) void IApiSwitch.RemoveWireDest(string destId) => RemoveWireDest(destId); void IApiCoil.OnCoil(bool enabled) { - if (enabled) { - var ringAnimation = EntityManager.GetComponentData(Entity); - ringAnimation.IsHit = true; - EntityManager.SetComponentData(Entity, ringAnimation); - } + // fixme job + // if (enabled) { + // var ringAnimation = EntityManager.GetComponentData(Entity); + // ringAnimation.IsHit = true; + // EntityManager.SetComponentData(Entity, ringAnimation); + // } } void IApiWireDest.OnChange(bool enabled) => (this as IApiCoil).OnCoil(enabled); @@ -95,10 +95,10 @@ void IApi.OnDestroy() { } - void IApiHittable.OnHit(Entity ballEntity, bool isUnHit) + void IApiHittable.OnHit(int ballId, bool isUnHit) { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); - Switch?.Invoke(this, new SwitchEventArgs(!isUnHit, ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); + Switch?.Invoke(this, new SwitchEventArgs(!isUnHit, ballId)); OnSwitch(true); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs index 616f8faa4..034f8fd6f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs @@ -67,7 +67,7 @@ public override void Bake(BumperComponent authoring) } // register at player - GetComponentInParent().RegisterBumper(authoring, GetEntity()); + GetComponentInParent().RegisterBumper(authoring); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs index bf24d7687..c166b36c5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs @@ -25,7 +25,7 @@ internal static class BumperCollider { public static void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, ref CollisionEventData collEvent, ref BumperRingAnimationData ringData, ref BumperSkirtAnimationData skirtData, - in Entity ballEntity, in Collider collider, in BumperStaticData data, ref Random random) + in int ballId, in Collider collider, in BumperStaticData data, ref Random random) { // todo // if (!m_enabled) return; @@ -42,7 +42,7 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle skirtData.HitEvent = true; skirtData.BallPosition = ball.Position; - events.Enqueue(new EventData(EventId.HitEventsHit, collider.Entity, ballEntity, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, collider.ItemId, ballId, true)); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs index 89c39eee6..e30b95b83 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs @@ -16,7 +16,6 @@ // ReSharper disable InconsistentNaming -using System; using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Bumper; @@ -45,8 +44,8 @@ public class BumperColliderComponent : ColliderComponent new BumperApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new BumperApi(gameObject, player); public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(scatterAngleDeg: Scatter); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs index 41d47fc80..b52766951 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs @@ -41,27 +41,28 @@ protected override void OnStartRunning() protected override void OnUpdate() { - var marker = PerfMarker; - Entities.WithoutBurst().WithName("BumperRingMovementJob").ForEach((Entity entity, in BumperRingAnimationData data) => { - - marker.Begin(); - - var transform = _player.BumperRingTransforms[entity]; - if (!_initialOffset.ContainsKey(entity)) { - _initialOffset[entity] = transform.position.y; - } - - var limit = data.DropOffset + data.HeightScale * 0.5f; - var localLimit = _initialOffset[entity] + limit; - var localOffset = localLimit / limit * data.Offset; - - var worldPos = transform.position; - worldPos.y = _initialOffset[entity] + VisualPinball.Unity.Physics.ScaleToWorld(localOffset); - transform.position = worldPos; - - marker.End(); - - }).Run(); + // fixme job + // var marker = PerfMarker; + // Entities.WithoutBurst().WithName("BumperRingMovementJob").ForEach((Entity entity, in BumperRingAnimationData data) => { + // + // marker.Begin(); + // + // var transform = _player.BumperRingTransforms[entity]; + // if (!_initialOffset.ContainsKey(entity)) { + // _initialOffset[entity] = transform.position.y; + // } + // + // var limit = data.DropOffset + data.HeightScale * 0.5f; + // var localLimit = _initialOffset[entity] + limit; + // var localOffset = localLimit / limit * data.Offset; + // + // var worldPos = transform.position; + // worldPos.y = _initialOffset[entity] + VisualPinball.Unity.Physics.ScaleToWorld(localOffset); + // transform.position = worldPos; + // + // marker.End(); + // + // }).Run(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs index b68e5a926..13369a26f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs @@ -38,18 +38,19 @@ protected override void OnStartRunning() protected override void OnUpdate() { - var marker = PerfMarker; - Entities.WithoutBurst().WithName("BumperSkirtMovementJob").ForEach((Entity entity, in BumperSkirtAnimationData data) => { - - marker.Begin(); - - var transform = _player.BumperSkirtTransforms[entity]; - var parentRotation = transform.parent.rotation; - transform.rotation = Quaternion.Euler(data.Rotation.x, 0, -data.Rotation.y) * parentRotation; - - marker.End(); - - }).Run(); + // fixme job + // var marker = PerfMarker; + // Entities.WithoutBurst().WithName("BumperSkirtMovementJob").ForEach((Entity entity, in BumperSkirtAnimationData data) => { + // + // marker.Begin(); + // + // var transform = _player.BumperSkirtTransforms[entity]; + // var parentRotation = transform.parent.rotation; + // transform.rotation = Quaternion.Euler(data.Rotation.x, 0, -data.Rotation.y) * parentRotation; + // + // marker.End(); + // + // }).Run(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs index 8a6a23291..0d9d7f24e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs @@ -28,28 +28,30 @@ public abstract class CollidableApi : I where TCollidableComponent : ColliderComponent where TData : ItemData { - public bool IsCollidable { - get => _simulateCycleSystemGroup != null && _simulateCycleSystemGroup.ItemsColliding[Entity]; + public bool IsCollidable + { + get => true; // fixme job _simulateCycleSystemGroup != null && _simulateCycleSystemGroup.ItemsColliding[Entity]; set { - if (_simulateCycleSystemGroup != null) { - _simulateCycleSystemGroup.ItemsColliding[Entity] = value; - } + // fixme job + // if (_simulateCycleSystemGroup != null) { + // _simulateCycleSystemGroup.ItemsColliding[Entity] = value; + // } } } - protected readonly Entity Entity; + protected readonly int ItemId; protected readonly TCollidableComponent ColliderComponent; private protected EntityManager EntityManager; private readonly SimulateCycleSystemGroup _simulateCycleSystemGroup; - protected CollidableApi(GameObject go, Entity entity, Player player) : base(go, player) + protected CollidableApi(GameObject go, Player player) : base(go, player) { if (World.DefaultGameObjectInjectionWorld != null) { _simulateCycleSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); } EntityManager = World.DefaultGameObjectInjectionWorld != null ? World.DefaultGameObjectInjectionWorld.EntityManager : default; - Entity = entity; + ItemId = go.GetInstanceID(); ColliderComponent = go.GetComponent(); } @@ -58,7 +60,6 @@ protected CollidableApi(GameObject go, Entity entity, Player player) : base(go, bool IApiColliderGenerator.IsColliderAvailable => ColliderComponent; bool IApiColliderGenerator.IsColliderEnabled => ColliderComponent && ColliderComponent.isActiveAndEnabled; - Entity IApiColliderGenerator.ColliderEntity => Entity; protected virtual bool FireHitEvents => false; protected virtual float HitThreshold => 0; @@ -82,7 +83,7 @@ public ColliderInfo GetColliderInfo(ItemType itemType) return new ColliderInfo { Id = -1, ItemType = itemType, - Entity = Entity, + ItemId = ItemId, FireEvents = FireHitEvents, IsEnabled = ColliderComponent && ColliderComponent.isActiveAndEnabled, Material = ColliderComponent.PhysicsMaterialData, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index b656ead52..b30944d41 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -59,7 +59,7 @@ public abstract class ColliderComponent : SubComponent _nonMeshColliders = new List(); [NonSerialized] private bool _collidersDirty; - protected abstract IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity); + protected abstract IApiColliderGenerator InstantiateColliderApi(Player player); public abstract PhysicsMaterialData PhysicsMaterialData { get; } @@ -121,7 +121,7 @@ private void OnDrawGizmos() var generateColliders = ShowAabbs || showColliders && !HasCachedColliders; if (generateColliders) { - var api = InstantiateColliderApi(player, _colliderEntity); + var api = InstantiateColliderApi(player); var colliders = new List(); api.CreateColliders(colliders, 0.1f); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs index 070322300..dc2d8de83 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs @@ -67,7 +67,7 @@ void IApi.OnInit(BallManager ballManager) private void OnHit(object sender, HitEventArgs e) { - Switch?.Invoke(this, new SwitchEventArgs(true, e.BallEntity)); + Switch?.Invoke(this, new SwitchEventArgs(true, e.BallId)); OnSwitch(true); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/EventArgs.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/EventArgs.cs index 274f76534..00f65a2f1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/EventArgs.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/EventArgs.cs @@ -33,23 +33,23 @@ public struct RotationEventArgs public struct HitEventArgs { - public Entity BallEntity; + public int BallId; - public HitEventArgs(Entity ballEntity) + public HitEventArgs(int ballId) { - BallEntity = ballEntity; + BallId = ballId; } } public readonly struct SwitchEventArgs { public readonly bool IsEnabled; - public readonly Entity BallEntity; + public readonly int BallId; - public SwitchEventArgs(bool isEnabled, Entity ballEntity) + public SwitchEventArgs(bool isEnabled, int ballId = 0) { IsEnabled = isEnabled; - BallEntity = ballEntity; + BallId = ballId; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs index fe8fc21e5..4a5ec50ca 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs @@ -71,8 +71,7 @@ public class FlipperApi : CollidableApi public void RotateToEnd() { - EngineProvider.Get().FlipperRotateToEnd(Entity); + EngineProvider.Get().FlipperRotateToEnd(ItemId); } /// @@ -104,15 +103,16 @@ public void RotateToEnd() /// public void RotateToStart() { - EngineProvider.Get().FlipperRotateToStart(Entity); + EngineProvider.Get().FlipperRotateToStart(ItemId); } internal float StartAngle { set { - var staticData = EntityManager.GetComponentData(Entity); - staticData.AngleStart = value; - EntityManager.SetComponentData(Entity, staticData); + // fixme job + // var staticData = EntityManager.GetComponentData(Entity); + // staticData.AngleStart = value; + // EntityManager.SetComponentData(Entity, staticData); } } @@ -165,7 +165,7 @@ private void OnDualWoundCoil(bool enabled, bool isHoldCoil) } else { if (_isEos && isHoldCoil) { _isEos = false; - Switch?.Invoke(this, new SwitchEventArgs(false, Entity.Null)); + Switch?.Invoke(this, new SwitchEventArgs(false)); OnSwitch(false); RotateToStart(); } @@ -191,9 +191,9 @@ private void OnDualWoundCoil(bool enabled, bool isHoldCoil) #region Events - void IApiHittable.OnHit(Entity ballEntity, bool _) + void IApiHittable.OnHit(int ballId, bool _) { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); } void IApiRotatable.OnRotate(float speed, bool direction) @@ -201,7 +201,7 @@ void IApiRotatable.OnRotate(float speed, bool direction) if (direction) { _isEos = true; LimitEos?.Invoke(this, new RotationEventArgs { AngleSpeed = speed }); - Switch?.Invoke(this, new SwitchEventArgs(true, Entity.Null)); + Switch?.Invoke(this, new SwitchEventArgs(true)); OnSwitch(true); } else { @@ -209,7 +209,7 @@ void IApiRotatable.OnRotate(float speed, bool direction) } } - void IApiCollidable.OnCollide(Entity ballEntity, float hit) + void IApiCollidable.OnCollide(int ballId, float hit) { Collide?.Invoke(this, new CollideEventArgs { FlipperHit = hit }); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs index afc8ac698..0aa7d56b9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs @@ -53,7 +53,7 @@ public override void Bake(FlipperComponent authoring) } // register - player.RegisterFlipper(authoring, GetEntity()); + player.RegisterFlipper(authoring); } private void SetupFlipperCorrection(FlipperComponent authoring, Player player, FlipperColliderComponent colliderComponent) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs index 8e61ecb25..aade98670 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs @@ -69,7 +69,7 @@ public FlipperCollider(CircleCollider hitCircleBase, float flipperRadius, float aabb = ExtendBoundsAtExtreme(aabb, c, flipperRadius, r2, r3, a0, a1, 90f); aabb = ExtendBoundsAtExtreme(aabb, c, flipperRadius, r2, r3, a0, a1, 180f); - Bounds = new ColliderBounds(_header.Entity, _header.Id, aabb); + Bounds = new ColliderBounds(_header.ItemId, _header.Id, aabb); } private static Aabb ExtendBoundsAtExtreme(Aabb aabb, float2 c, float length, float endRadius, float startRadius, float startAngle, float endAngle, float angle) @@ -777,7 +777,7 @@ public static void LiveCatch(ref BallData ball, ref CollisionEventData collEvent #region Collision public void Collide(ref BallData ball, ref CollisionEventData collEvent, ref FlipperMovementData movementData, - ref NativeQueue.ParallelWriter events, in Entity ballEntity, in FlipperTricksData tricks, in FlipperStaticData matData, + ref NativeQueue.ParallelWriter events, in int ballId, in FlipperTricksData tricks, in FlipperStaticData matData, in FlipperVelocityData velData, in FlipperHitData hitData, uint timeMsec) { var normal = collEvent.HitNormal; @@ -915,11 +915,11 @@ public void Collide(ref BallData ball, ref CollisionEventData collEvent, ref Fli var flipperHit = hitData.HitMomentBit ? -1.0f : -bnv; // move event processing to end of collision handler... if (flipperHit < 0f) { // simple hit event - events.Enqueue(new EventData(EventId.HitEventsHit, _header.Entity, ballEntity, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, _header.ItemId, ballId, true)); } else { // collision velocity (normal to face) - events.Enqueue(new EventData(EventId.FlipperEventsCollide, _header.Entity, ballEntity, flipperHit)); + events.Enqueue(new EventData(EventId.FlipperEventsCollide, _header.ItemId, ballId, flipperHit)); } } movementData.LastHitTime = timeMsec; // keep resetting until idle for 250 milliseconds diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs index 155bf5426..0fbc0edf7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs @@ -157,8 +157,8 @@ public class FlipperColliderComponent : ColliderComponent new FlipperApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new FlipperApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs index 0dd3abe7d..184b41fa6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs @@ -54,69 +54,70 @@ protected override void OnUpdate() var marker = PerfMarker; var currentTime = SystemAPI.Time.ElapsedTime; - Entities.WithName("FlipperDisplacementJob").ForEach((Entity entity, ref FlipperMovementData state, ref FlipperTricksData tricks, in FlipperStaticData data) => { - - marker.Begin(); - - state.Angle += state.AngleSpeed * dTime; // move flipper angle - - var angleMin = math.min(data.AngleStart, tricks.AngleEnd); - var angleMax = math.max(data.AngleStart, tricks.AngleEnd); - - if (state.Angle > angleMax) { - state.Angle = angleMax; - } - - if (state.Angle < angleMin) { - state.Angle = angleMin; - } - - if (math.abs(state.AngleSpeed) < 0.0005f) { - // avoids "jumping balls" when two or more balls held on flipper (and more other balls are in play) //!! make dependent on physics update rate - marker.End(); - return; - } - - var handleEvent = false; - - if (state.Angle == tricks.AngleEnd) { - tricks.FlipperAngleEndTime = currentTime; - } - - if (state.Angle >= angleMax) { - // hit stop? - if (state.AngleSpeed > 0) { - handleEvent = true; - } - - } else if (state.Angle <= angleMin) { - if (state.AngleSpeed < 0) { - handleEvent = true; - } - } - - if (handleEvent) { - var angleSpeed = math.abs(math.degrees(state.AngleSpeed)); - state.AngularMomentum *= -0.3f; // make configurable? - state.AngleSpeed = state.AngularMomentum / data.Inertia; - - if (state.EnableRotateEvent > 0) { - - // send EOS event - events.Enqueue(new EventData(EventId.LimitEventsEos, entity, angleSpeed)); - - } else if (state.EnableRotateEvent < 0) { - - // send BOS event - events.Enqueue(new EventData(EventId.LimitEventsBos, entity, angleSpeed)); - } - - state.EnableRotateEvent = 0; - } - - marker.End(); - - }).Run(); + // fixme job + // Entities.WithName("FlipperDisplacementJob").ForEach((Entity entity, ref FlipperMovementData state, ref FlipperTricksData tricks, in FlipperStaticData data) => { + // + // marker.Begin(); + // + // state.Angle += state.AngleSpeed * dTime; // move flipper angle + // + // var angleMin = math.min(data.AngleStart, tricks.AngleEnd); + // var angleMax = math.max(data.AngleStart, tricks.AngleEnd); + // + // if (state.Angle > angleMax) { + // state.Angle = angleMax; + // } + // + // if (state.Angle < angleMin) { + // state.Angle = angleMin; + // } + // + // if (math.abs(state.AngleSpeed) < 0.0005f) { + // // avoids "jumping balls" when two or more balls held on flipper (and more other balls are in play) //!! make dependent on physics update rate + // marker.End(); + // return; + // } + // + // var handleEvent = false; + // + // if (state.Angle == tricks.AngleEnd) { + // tricks.FlipperAngleEndTime = currentTime; + // } + // + // if (state.Angle >= angleMax) { + // // hit stop? + // if (state.AngleSpeed > 0) { + // handleEvent = true; + // } + // + // } else if (state.Angle <= angleMin) { + // if (state.AngleSpeed < 0) { + // handleEvent = true; + // } + // } + // + // if (handleEvent) { + // var angleSpeed = math.abs(math.degrees(state.AngleSpeed)); + // state.AngularMomentum *= -0.3f; // make configurable? + // state.AngleSpeed = state.AngularMomentum / data.Inertia; + // + // if (state.EnableRotateEvent > 0) { + // + // // send EOS event + // events.Enqueue(new EventData(EventId.LimitEventsEos, entity, angleSpeed)); + // + // } else if (state.EnableRotateEvent < 0) { + // + // // send BOS event + // events.Enqueue(new EventData(EventId.LimitEventsBos, entity, angleSpeed)); + // } + // + // state.EnableRotateEvent = 0; + // } + // + // marker.End(); + // + // }).Run(); // dequeue events while (_eventQueue.TryDequeue(out var eventData)) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs index bc2926502..d7d2761e8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs @@ -39,16 +39,17 @@ protected override void OnStartRunning() protected override void OnUpdate() { - var marker = PerfMarker; - Entities.WithoutBurst().WithName("FlipperRotateJob").ForEach((Entity entity, in FlipperMovementData movement) => { - - marker.Begin(); - - _player.FlipperTransforms[entity].localRotation = quaternion.Euler(0, movement.Angle, 0); - - marker.End(); - - }).Run(); + // fixme job + // var marker = PerfMarker; + // Entities.WithoutBurst().WithName("FlipperRotateJob").ForEach((Entity entity, in FlipperMovementData movement) => { + // + // marker.Begin(); + // + // _player.FlipperTransforms[entity].localRotation = quaternion.Euler(0, movement.Angle, 0); + // + // marker.End(); + // + // }).Run(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs index 08847e285..3fae7c340 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs @@ -16,8 +16,6 @@ using System; using System.Collections.Generic; -using Unity.Entities; -using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.VPT.Gate; @@ -74,18 +72,18 @@ public class GateApi : CollidableApi(Entity); - data.IsLifting = true; - data.LiftSpeed = speed; - data.LiftAngle = math.radians(angleDeg); - EntityManager.SetComponentData(Entity, data); + // fixme job + // var data = EntityManager.GetComponentData(Entity); + // data.IsLifting = true; + // data.LiftSpeed = speed; + // data.LiftAngle = math.radians(angleDeg); + // EntityManager.SetComponentData(Entity, data); } #region Wiring @@ -121,10 +119,10 @@ void IApi.OnDestroy() { } - void IApiHittable.OnHit(Entity ballEntity, bool _) + void IApiHittable.OnHit(int ballId, bool _) { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); - Switch?.Invoke(this, new SwitchEventArgs(true, ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); + Switch?.Invoke(this, new SwitchEventArgs(true, ballId)); OnSwitch(true); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs index 67563a1ea..f339fe06b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs @@ -53,7 +53,7 @@ public override void Bake(GateComponent authoring) } // register - GetComponentInParent().RegisterGate(authoring, GetEntity()); + GetComponentInParent().RegisterGate(authoring); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs index ce6b4a1dc..368f25e90 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs @@ -86,7 +86,7 @@ public float HitTest(ref CollisionEventData collEvent, ref DynamicBuffer.ParallelWriter events, in Entity ballEntity, in Collider coll, in GateStaticData data) + ref NativeQueue.ParallelWriter events, in int ballId, in Collider coll, in GateStaticData data) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); var h = data.Height * 0.5f; @@ -114,7 +114,7 @@ public static void Collide(ref BallData ball, ref CollisionEventData collEvent, movementData.AngleSpeed = -movementData.AngleSpeed; } - Collider.FireHitEvent(ref ball, ref events, in ballEntity, in coll.Header); + Collider.FireHitEvent(ref ball, ref events, in ballId, in coll.Header); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs index 1508a6c7c..5412d7626 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs @@ -68,7 +68,7 @@ public class GateColliderComponent : ColliderComponent, public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(Elasticity, friction: Friction); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new GateApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new GateApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs index fe96e4822..4b6c53e14 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs @@ -52,87 +52,88 @@ protected override void OnUpdate() var marker = PerfMarker; var events = _eventQueue.AsParallelWriter(); - Entities - .WithName("GateDisplacementJob") - .ForEach((Entity entity, ref GateMovementData movementData, in GateStaticData data) => { - - marker.Begin(); - - if (data.TwoWay) { - if (math.abs(movementData.Angle) > data.AngleMax) { - if (movementData.Angle < 0.0) { - movementData.Angle = -data.AngleMax; - } else { - movementData.Angle = data.AngleMax; - } - - // send EOS event - events.Enqueue(new EventData(EventId.LimitEventsEos, entity, movementData.AngleSpeed)); - - if (!movementData.ForcedMove) { - movementData.AngleSpeed = -movementData.AngleSpeed; - movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - } else if (movementData.AngleSpeed > 0.0) { - movementData.AngleSpeed = 0.0f; - } - } - if (math.abs(movementData.Angle) < data.AngleMin) { - if (movementData.Angle < 0.0) { - movementData.Angle = -data.AngleMin; - } else { - movementData.Angle = data.AngleMin; - } - if (!movementData.ForcedMove) { - movementData.AngleSpeed = -movementData.AngleSpeed; - movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - } else if (movementData.AngleSpeed < 0.0) { - movementData.AngleSpeed = 0.0f; - } - } - } else { - var direction = movementData.HitDirection ? -1f : 1f; - if (direction * movementData.Angle > data.AngleMax) { - movementData.Angle = direction * data.AngleMax; - - // send EOS event - events.Enqueue(new EventData(EventId.LimitEventsEos, entity, movementData.AngleSpeed)); - - if (!movementData.ForcedMove) { - movementData.AngleSpeed = -movementData.AngleSpeed; - movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - } else if (movementData.AngleSpeed > 0.0) { - movementData.AngleSpeed = 0.0f; - } - } - if (direction * movementData.Angle < data.AngleMin) { - movementData.Angle = direction * data.AngleMin; - - // send Park event - events.Enqueue(new EventData(EventId.LimitEventsBos, entity, movementData.AngleSpeed)); - - if (!movementData.ForcedMove) { - movementData.AngleSpeed = -movementData.AngleSpeed; - movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - } else if (movementData.AngleSpeed < 0.0) { - movementData.AngleSpeed = 0.0f; - } - } - } - movementData.Angle += movementData.AngleSpeed * dTime; - - if (movementData.IsLifting) { - if (math.abs(movementData.Angle - movementData.LiftAngle) > 0.000001f) { - var direction = movementData.Angle < movementData.LiftAngle ? 1f : -1f; - movementData.Angle += direction * (movementData.LiftSpeed * dTime); - - } else { - movementData.IsLifting = false; - } - } - - marker.End(); - - }).Run(); + // fixme job + // Entities + // .WithName("GateDisplacementJob") + // .ForEach((Entity entity, ref GateMovementData movementData, in GateStaticData data) => { + // + // marker.Begin(); + // + // if (data.TwoWay) { + // if (math.abs(movementData.Angle) > data.AngleMax) { + // if (movementData.Angle < 0.0) { + // movementData.Angle = -data.AngleMax; + // } else { + // movementData.Angle = data.AngleMax; + // } + // + // // send EOS event + // events.Enqueue(new EventData(EventId.LimitEventsEos, entity, movementData.AngleSpeed)); + // + // if (!movementData.ForcedMove) { + // movementData.AngleSpeed = -movementData.AngleSpeed; + // movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + // } else if (movementData.AngleSpeed > 0.0) { + // movementData.AngleSpeed = 0.0f; + // } + // } + // if (math.abs(movementData.Angle) < data.AngleMin) { + // if (movementData.Angle < 0.0) { + // movementData.Angle = -data.AngleMin; + // } else { + // movementData.Angle = data.AngleMin; + // } + // if (!movementData.ForcedMove) { + // movementData.AngleSpeed = -movementData.AngleSpeed; + // movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + // } else if (movementData.AngleSpeed < 0.0) { + // movementData.AngleSpeed = 0.0f; + // } + // } + // } else { + // var direction = movementData.HitDirection ? -1f : 1f; + // if (direction * movementData.Angle > data.AngleMax) { + // movementData.Angle = direction * data.AngleMax; + // + // // send EOS event + // events.Enqueue(new EventData(EventId.LimitEventsEos, entity, movementData.AngleSpeed)); + // + // if (!movementData.ForcedMove) { + // movementData.AngleSpeed = -movementData.AngleSpeed; + // movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + // } else if (movementData.AngleSpeed > 0.0) { + // movementData.AngleSpeed = 0.0f; + // } + // } + // if (direction * movementData.Angle < data.AngleMin) { + // movementData.Angle = direction * data.AngleMin; + // + // // send Park event + // events.Enqueue(new EventData(EventId.LimitEventsBos, entity, movementData.AngleSpeed)); + // + // if (!movementData.ForcedMove) { + // movementData.AngleSpeed = -movementData.AngleSpeed; + // movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + // } else if (movementData.AngleSpeed < 0.0) { + // movementData.AngleSpeed = 0.0f; + // } + // } + // } + // movementData.Angle += movementData.AngleSpeed * dTime; + // + // if (movementData.IsLifting) { + // if (math.abs(movementData.Angle - movementData.LiftAngle) > 0.000001f) { + // var direction = movementData.Angle < movementData.LiftAngle ? 1f : -1f; + // movementData.Angle += direction * (movementData.LiftSpeed * dTime); + // + // } else { + // movementData.IsLifting = false; + // } + // } + // + // marker.End(); + // + // }).Run(); // dequeue events while (_eventQueue.TryDequeue(out var eventData)) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs index 4795bc1d9..2aa672637 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs @@ -38,16 +38,17 @@ protected override void OnStartRunning() protected override void OnUpdate() { - var marker = PerfMarker; - Entities.WithoutBurst().WithName("GateMovementJob").ForEach((Entity entity, in GateMovementData movementData) => { - - marker.Begin(); - - _player.GateWireTransforms[entity].localRotation = quaternion.RotateX(-movementData.Angle); - - marker.End(); - - }).Run(); + // fixme job + // var marker = PerfMarker; + // Entities.WithoutBurst().WithName("GateMovementJob").ForEach((Entity entity, in GateMovementData movementData) => { + // + // marker.Begin(); + // + // _player.GateWireTransforms[entity].localRotation = quaternion.RotateX(-movementData.Angle); + // + // marker.End(); + // + // }).Run(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs index a5996fe24..c4f8adbe8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs @@ -51,63 +51,64 @@ protected override void OnUpdate() var events = _eventQueue.AsParallelWriter(); var marker = PerfMarker; - Entities - .WithName("HitTargetAnimationJob") - .ForEach((Entity entity, ref DropTargetAnimationData data, in DropTargetStaticData staticData) => - { - marker.Begin(); - - var oldTimeMsec = data.TimeMsec < timeMsec ? data.TimeMsec : timeMsec; - data.TimeMsec = timeMsec; - var diffTimeMsec = (float)(timeMsec - oldTimeMsec); - - if (data.HitEvent) { - if (!data.IsDropped) { - data.MoveDown = true; - } - - data.MoveAnimation = true; - data.HitEvent = false; - } - - if (data.MoveAnimation) { - var step = staticData.Speed; - - if (data.MoveDown) { - step = -step; - - } else if (data.TimeMsec - data.TimeStamp < (uint) staticData.RaiseDelay) { - step = 0.0f; - } - - data.ZOffset += step * diffTimeMsec; - if (data.MoveDown) { - if (data.ZOffset <= -DropTargetAnimationData.DropTargetLimit) { - data.ZOffset = -DropTargetAnimationData.DropTargetLimit; - data.MoveDown = false; - data.IsDropped = true; - data.MoveAnimation = false; - data.TimeStamp = 0; - if (staticData.UseHitEvent) { - events.Enqueue(new EventData(EventId.TargetEventsDropped, entity)); - } - } - - } else { - if (data.ZOffset >= 0.0f) { - data.ZOffset = 0.0f; - data.MoveAnimation = false; - data.IsDropped = false; - if (staticData.UseHitEvent) { - events.Enqueue(new EventData(EventId.TargetEventsRaised, entity)); - } - } - } - } - - marker.End(); - - }).Run(); + // fixme job + // Entities + // .WithName("HitTargetAnimationJob") + // .ForEach((Entity entity, ref DropTargetAnimationData data, in DropTargetStaticData staticData) => + // { + // marker.Begin(); + // + // var oldTimeMsec = data.TimeMsec < timeMsec ? data.TimeMsec : timeMsec; + // data.TimeMsec = timeMsec; + // var diffTimeMsec = (float)(timeMsec - oldTimeMsec); + // + // if (data.HitEvent) { + // if (!data.IsDropped) { + // data.MoveDown = true; + // } + // + // data.MoveAnimation = true; + // data.HitEvent = false; + // } + // + // if (data.MoveAnimation) { + // var step = staticData.Speed; + // + // if (data.MoveDown) { + // step = -step; + // + // } else if (data.TimeMsec - data.TimeStamp < (uint) staticData.RaiseDelay) { + // step = 0.0f; + // } + // + // data.ZOffset += step * diffTimeMsec; + // if (data.MoveDown) { + // if (data.ZOffset <= -DropTargetAnimationData.DropTargetLimit) { + // data.ZOffset = -DropTargetAnimationData.DropTargetLimit; + // data.MoveDown = false; + // data.IsDropped = true; + // data.MoveAnimation = false; + // data.TimeStamp = 0; + // if (staticData.UseHitEvent) { + // events.Enqueue(new EventData(EventId.TargetEventsDropped, entity)); + // } + // } + // + // } else { + // if (data.ZOffset >= 0.0f) { + // data.ZOffset = 0.0f; + // data.MoveAnimation = false; + // data.IsDropped = false; + // if (staticData.UseHitEvent) { + // events.Enqueue(new EventData(EventId.TargetEventsRaised, entity)); + // } + // } + // } + // } + // + // marker.End(); + // + // }).Run(); // dequeue events while (_eventQueue.TryDequeue(out var eventData)) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs index dda9610aa..24b4b15b7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs @@ -16,10 +16,8 @@ using System; using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.HitTarget; -using VisualPinballUnity; namespace VisualPinball.Unity { @@ -52,19 +50,18 @@ public class DropTargetApi : CollidableApiThrown if target is not a drop target (but a hit target, which can't be dropped) public bool IsDropped { - get => EntityManager.GetComponentData(Entity).IsDropped; + get => false; // fixme job EntityManager.GetComponentData(Entity).IsDropped; set => SetIsDropped(value); } - internal DropTargetApi(GameObject go, Entity entity, Player player) - : base(go, entity, player) + internal DropTargetApi(GameObject go, Player player) : base(go, player) { } - public void OnDropStatusChanged(bool isDropped, Entity ballEntity) + public void OnDropStatusChanged(bool isDropped, int ballId) { OnSwitch(isDropped); - Switch?.Invoke(this, new SwitchEventArgs(isDropped, ballEntity)); + Switch?.Invoke(this, new SwitchEventArgs(isDropped, ballId)); } /// @@ -74,21 +71,22 @@ public void OnDropStatusChanged(bool isDropped, Entity ballEntity) /// private void SetIsDropped(bool isDropped) { - var data = EntityManager.GetComponentData(Entity); - if (data.IsDropped != isDropped) { - data.MoveAnimation = true; - if (isDropped) { - data.MoveDown = true; - } - else { - data.MoveDown = false; - data.TimeStamp = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged().TimeMsec; - } - } else { - data.IsDropped = isDropped; - } - - EntityManager.SetComponentData(Entity, data); + // fixme job + // var data = EntityManager.GetComponentData(Entity); + // if (data.IsDropped != isDropped) { + // data.MoveAnimation = true; + // if (isDropped) { + // data.MoveDown = true; + // } + // else { + // data.MoveDown = false; + // data.TimeStamp = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged().TimeMsec; + // } + // } else { + // data.IsDropped = isDropped; + // } + // + // EntityManager.SetComponentData(Entity, data); } #region Wiring @@ -127,9 +125,9 @@ void IApi.OnDestroy() { } - void IApiHittable.OnHit(Entity ballEntity, bool _) + void IApiHittable.OnHit(int ballId, bool _) { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs index 943962082..828a17450 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs @@ -42,7 +42,7 @@ public override void Bake(DropTargetComponent authoring) } // register - GetComponentInParent().RegisterDropTarget(authoring, GetEntity()); + GetComponentInParent().RegisterDropTarget(authoring); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs index dc262808b..e111a8d36 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs @@ -62,7 +62,7 @@ public class DropTargetColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new DropTargetApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new DropTargetApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs index 27b018a18..e07ff5d81 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs @@ -37,21 +37,22 @@ protected override void OnStartRunning() protected override void OnUpdate() { - var marker = PerfMarker; - Entities.WithoutBurst().WithName("DropTargetTransformationJob").ForEach((Entity entity, in DropTargetAnimationData data) => - { - marker.Begin(); - - var localPos = _player.DropTargetTransforms[entity].localPosition; - _player.DropTargetTransforms[entity].localPosition = new Vector3( - localPos.x, - VisualPinball.Unity.Physics.ScaleToWorld(data.ZOffset), - localPos.z - ); - - marker.End(); - - }).Run(); + // fixme job + // var marker = PerfMarker; + // Entities.WithoutBurst().WithName("DropTargetTransformationJob").ForEach((Entity entity, in DropTargetAnimationData data) => + // { + // marker.Begin(); + // + // var localPos = _player.DropTargetTransforms[entity].localPosition; + // _player.DropTargetTransforms[entity].localPosition = new Vector3( + // localPos.x, + // VisualPinball.Unity.Physics.ScaleToWorld(data.ZOffset), + // localPos.z + // ); + // + // marker.End(); + // + // }).Run(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs index 9ed73a566..53f27b3a4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs @@ -16,7 +16,6 @@ using System; using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.HitTarget; @@ -40,8 +39,7 @@ public class HitTargetApi : CollidableApi public event EventHandler Switch; - internal HitTargetApi(GameObject go, Entity entity, Player player) - : base(go, entity, player) + internal HitTargetApi(GameObject go, Player player) : base(go, player) { } @@ -81,10 +79,10 @@ void IApi.OnDestroy() { } - void IApiHittable.OnHit(Entity ballEntity, bool _) + void IApiHittable.OnHit(int ballId, bool _) { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); - Switch?.Invoke(this, new SwitchEventArgs(true, ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); + Switch?.Invoke(this, new SwitchEventArgs(true, ballId)); OnSwitch(true); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs index 16525ff5c..1bd247a13 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs @@ -39,7 +39,7 @@ public override void Bake(HitTargetComponent authoring) } // register - GetComponentInParent().RegisterHitTarget(authoring, GetEntity()); + GetComponentInParent().RegisterHitTarget(authoring); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs index a222e4969..9fc9cb2f1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs @@ -56,7 +56,7 @@ public class HitTargetColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new HitTargetApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new HitTargetApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs index 73c67437e..26313e7e6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs @@ -36,22 +36,23 @@ protected override void OnStartRunning() protected override void OnUpdate() { - var marker = PerfMarker; - Entities.WithoutBurst().WithName("HitTargetTransformationJob").ForEach((Entity entity, - in HitTargetAnimationData data, in HitTargetStaticData staticData) => - { - marker.Begin(); - - var localRot = _player.HitTargetTransforms[entity].transform.localEulerAngles; - _player.HitTargetTransforms[entity].transform.localEulerAngles = new Vector3( - data.XRotation, - localRot.y, - localRot.z - ); - - marker.End(); - - }).Run(); + // fixme job + // var marker = PerfMarker; + // Entities.WithoutBurst().WithName("HitTargetTransformationJob").ForEach((Entity entity, + // in HitTargetAnimationData data, in HitTargetStaticData staticData) => + // { + // marker.Begin(); + // + // var localRot = _player.HitTargetTransforms[entity].transform.localEulerAngles; + // _player.HitTargetTransforms[entity].transform.localEulerAngles = new Vector3( + // data.XRotation, + // localRot.y, + // localRot.z + // ); + // + // marker.End(); + // + // }).Run(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs index 086f07dcb..6176fa7f6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity internal static class TargetCollider { public static void DropTargetCollide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, - ref DropTargetAnimationData animationData, in float3 normal, in Entity ballEntity, in CollisionEventData collEvent, + ref DropTargetAnimationData animationData, in float3 normal, in int ballId, in CollisionEventData collEvent, in Collider coll, ref Random random) { if (animationData.IsDropped) { @@ -36,12 +36,12 @@ public static void DropTargetCollide(ref BallData ball, ref NativeQueue= coll.Threshold && !animationData.IsDropped) { animationData.HitEvent = true; //todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in ballEntity, in coll.Header); + Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in coll.Header); } } public static void HitTargetCollide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, - ref HitTargetAnimationData animationData, in float3 normal, in Entity ballEntity, in CollisionEventData collEvent, + ref HitTargetAnimationData animationData, in float3 normal, in int ballId, in CollisionEventData collEvent, in Collider coll, ref Random random) { var dot = -math.dot(collEvent.HitNormal, ball.Velocity); @@ -50,7 +50,7 @@ public static void HitTargetCollide(ref BallData ball, ref NativeQueue= coll.Threshold) { animationData.HitEvent = true; //todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in ballEntity, in coll.Header); + Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in coll.Header); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs index 0f6fb7f95..1eea5f548 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs @@ -52,11 +52,6 @@ public interface IApiColliderGenerator /// ColliderInfo GetColliderInfo(); - /// - /// The entity of the game item - /// - Entity ColliderEntity { get; } - /// /// If false, this will be included in the quad tree but marked as inactive. /// @@ -78,7 +73,7 @@ public interface IApiHittable /// /// Which ball /// Whether it exited the hittable area - void OnHit(Entity ballEntity, bool isUnHit = false); + void OnHit(int ballId, bool isUnHit = false); /// /// Public event to subscribe to for hits. @@ -104,7 +99,7 @@ internal interface IApiRotatable /// internal interface IApiCollidable { - void OnCollide(Entity ballEntity, float hit); + void OnCollide(int ballId, float hit); } /// @@ -120,7 +115,7 @@ internal interface IApiSpinnable /// internal interface IApiSlingshot { - void OnSlingshot(Entity ballEntity); + void OnSlingshot(int ballId); } /// @@ -128,7 +123,7 @@ internal interface IApiSlingshot /// internal interface IApiDroppable { - void OnDropStatusChanged(bool isDropped, Entity ballEntity); + void OnDropStatusChanged(bool isDropped, int ballId); } /// diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs index 2d387eacd..39a8fccb2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using Unity.Entities; using Unity.Mathematics; @@ -54,8 +55,7 @@ public class KickerApi : CollidableApi _coils = new Dictionary(); - public KickerApi(GameObject go, Entity entity, Player player) - : base(go, entity, player) + public KickerApi(GameObject go, Player player) : base(go, player) { foreach (var coil in MainComponent.Coils) { _coils[coil.Id] = new KickerDeviceCoil(player, coil, this); @@ -74,22 +74,22 @@ void IApi.OnDestroy() public void CreateBall() { - BallManager.CreateBall(MainComponent, 25f, 1f, Entity); + BallManager.CreateBall(MainComponent, 25f, 1f, ItemId); } public void CreateSizedBallWithMass(float radius, float mass) { - BallManager.CreateBall(MainComponent, radius, mass, Entity); + BallManager.CreateBall(MainComponent, radius, mass, ItemId); } public void CreateSizedBall(float radius) { - BallManager.CreateBall(MainComponent, radius, 1f, Entity); + BallManager.CreateBall(MainComponent, radius, 1f, ItemId); } public void Kick(float angle, float speed, float inclination = 0) { - SimulationSystemGroup.QueueAfterBallCreation(() => KickXYZ(Entity, angle, speed, inclination, 0, 0, 0)); + SimulationSystemGroup.QueueAfterBallCreation(() => KickXYZ(ItemId, angle, speed, inclination, 0, 0, 0)); } /// @@ -101,13 +101,14 @@ public void Kick(float angle, float speed, float inclination = 0) /// public void DestroyBall() { - var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - var kickerCollisionData = entityManager.GetComponentData(Entity); - var ballEntity = kickerCollisionData.BallEntity; - if (ballEntity != Entity.Null) { - BallManager.DestroyEntity(ballEntity); - SimulationSystemGroup.QueueAfterBallCreation(OnBallDestroyed); - } + // fixme job + // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; + // var kickerCollisionData = entityManager.GetComponentData(Entity); + // var ballEntity = kickerCollisionData.BallId; + // if (ballEntity != Entity.Null) { + // BallManager.DestroyEntity(ballEntity); + // SimulationSystemGroup.QueueAfterBallCreation(OnBallDestroyed); + // } } /// @@ -116,26 +117,33 @@ public void DestroyBall() /// True if there is a ball in the kicker, false otherwise. public bool HasBall() { - var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - var kickerCollisionData = entityManager.GetComponentData(Entity); - return kickerCollisionData.HasBall; + // fixme job + // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; + // var kickerCollisionData = entityManager.GetComponentData(Entity); + // return kickerCollisionData.HasBall; + return false; } internal BallData GetBallData() { - var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - var kickerCollisionData = entityManager.GetComponentData(Entity); - return kickerCollisionData.HasBall - ? entityManager.GetComponentData(kickerCollisionData.BallEntity) - : default; + // fixme job + // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; + // var kickerCollisionData = entityManager.GetComponentData(Entity); + // return kickerCollisionData.HasBall + // ? entityManager.GetComponentData(kickerCollisionData.BallId) + // : default; + return default; } - internal Entity BallEntity + internal int BallId { - get { - var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - var kickerCollisionData = entityManager.GetComponentData(Entity); - return kickerCollisionData.BallEntity; + get + { + return 0; + // fixme job + // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; + // var kickerCollisionData = entityManager.GetComponentData(Entity); + // return kickerCollisionData.BallId; } } @@ -161,78 +169,79 @@ private IApiCoil Coil(string deviceItem) private void OnBallDestroyed() { - var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - var kickerCollisionData = entityManager.GetComponentData(Entity); - var ballEntity = kickerCollisionData.BallEntity; - if (ballEntity != Entity.Null) { - - // update kicker status - kickerCollisionData.BallEntity = Entity.Null; - entityManager.SetComponentData(Entity, kickerCollisionData); - } + // fixme job + // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; + // var kickerCollisionData = entityManager.GetComponentData(Entity); + // if (kickerCollisionData.BallId != 0) { + // + // // update kicker status + // kickerCollisionData.BallId = kickerCollisionData.BallId; + // entityManager.SetComponentData(Entity, kickerCollisionData); + // } } #endregion - private void KickXYZ(Entity kickerEntity, float angle, float speed, float inclination, float x, float y, float z) + private void KickXYZ(int kickerId, float angle, float speed, float inclination, float x, float y, float z) { - var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - var kickerCollisionData = entityManager.GetComponentData(kickerEntity); - var kickerStaticData = entityManager.GetComponentData(kickerEntity); - var ballEntity = kickerCollisionData.BallEntity; - if (ballEntity != Entity.Null) { - var angleRad = math.radians(angle); // yaw angle, zero is along -Y axis - - if (math.abs(inclination) > (float) (System.Math.PI / 2.0)) { - // radians or degrees? if greater PI/2 assume degrees - inclination *= (float) (System.Math.PI / 180.0); // convert to radians - } - - // if < 0 use global value - var scatterAngle = kickerStaticData.Scatter < 0.0f ? 0.0f : math.radians(kickerStaticData.Scatter); - scatterAngle *= TableComponent.GlobalDifficulty; // apply difficulty weighting - - if (scatterAngle > 1.0e-5f) { // ignore near zero angles - var scatter = new Random().NextFloat(-1f, 1f); // -1.0f..1.0f - scatter *= (1.0f - scatter * scatter) * 2.59808f * scatterAngle; // shape quadratic distribution and scale - angleRad += scatter; - } - - var speedZ = math.sin(inclination) * speed; - if (speedZ > 0.0f) { - speed *= math.cos(inclination); - } - - // update ball data - var ballData = entityManager.GetComponentData(ballEntity); - ballData.Position = new float3( - ballData.Position.x + x, - ballData.Position.y + y, - ballData.Position.z + z - ); - ballData.Velocity = new float3( - math.sin(angleRad) * speed, - -math.cos(angleRad) * speed, - speedZ - ); - ballData.IsFrozen = false; - ballData.AngularMomentum = float3.zero; - entityManager.SetComponentData(ballEntity, ballData); - - // update collision event - var collEvent = entityManager.GetComponentData(ballEntity); - collEvent.HitDistance = 0.0f; - collEvent.HitTime = -1.0f; - collEvent.HitNormal = float3.zero; - collEvent.HitVelocity = float2.zero; - collEvent.HitFlag = false; - collEvent.IsContact = false; - entityManager.SetComponentData(ballEntity, collEvent); - - // update kicker status - kickerCollisionData.BallEntity = Entity.Null; - entityManager.SetComponentData(kickerEntity, kickerCollisionData); - } + // fixme jobs + // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; + // var kickerCollisionData = entityManager.GetComponentData(kickerEntity); + // var kickerStaticData = entityManager.GetComponentData(kickerEntity); + // var ballEntity = kickerCollisionData.BallId; + // if (ballEntity != Entity.Null) { + // var angleRad = math.radians(angle); // yaw angle, zero is along -Y axis + // + // if (math.abs(inclination) > (float) (System.Math.PI / 2.0)) { + // // radians or degrees? if greater PI/2 assume degrees + // inclination *= (float) (System.Math.PI / 180.0); // convert to radians + // } + // + // // if < 0 use global value + // var scatterAngle = kickerStaticData.Scatter < 0.0f ? 0.0f : math.radians(kickerStaticData.Scatter); + // scatterAngle *= TableComponent.GlobalDifficulty; // apply difficulty weighting + // + // if (scatterAngle > 1.0e-5f) { // ignore near zero angles + // var scatter = new Random().NextFloat(-1f, 1f); // -1.0f..1.0f + // scatter *= (1.0f - scatter * scatter) * 2.59808f * scatterAngle; // shape quadratic distribution and scale + // angleRad += scatter; + // } + // + // var speedZ = math.sin(inclination) * speed; + // if (speedZ > 0.0f) { + // speed *= math.cos(inclination); + // } + // + // // update ball data + // var ballData = entityManager.GetComponentData(ballEntity); + // ballData.Position = new float3( + // ballData.Position.x + x, + // ballData.Position.y + y, + // ballData.Position.z + z + // ); + // ballData.Velocity = new float3( + // math.sin(angleRad) * speed, + // -math.cos(angleRad) * speed, + // speedZ + // ); + // ballData.IsFrozen = false; + // ballData.AngularMomentum = float3.zero; + // entityManager.SetComponentData(ballEntity, ballData); + // + // // update collision event + // var collEvent = entityManager.GetComponentData(ballEntity); + // collEvent.HitDistance = 0.0f; + // collEvent.HitTime = -1.0f; + // collEvent.HitNormal = float3.zero; + // collEvent.HitVelocity = float2.zero; + // collEvent.HitFlag = false; + // collEvent.IsContact = false; + // entityManager.SetComponentData(ballEntity, collEvent); + // + // // update kicker status + // kickerCollisionData.BallId = Entity.Null; + // entityManager.SetComponentData(kickerEntity, kickerCollisionData); + // } } IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => AddSwitchDest(switchConfig.WithPulse(false), switchStatus); @@ -256,16 +265,16 @@ protected override void CreateColliders(List colliders, float margin) #region Events - void IApiHittable.OnHit(Entity ballEntity, bool isUnHit) + void IApiHittable.OnHit(int ballId, bool isUnHit) { if (isUnHit) { - UnHit?.Invoke(this, new HitEventArgs(ballEntity)); - Switch?.Invoke(this, new SwitchEventArgs(false, ballEntity)); + UnHit?.Invoke(this, new HitEventArgs(ballId)); + Switch?.Invoke(this, new SwitchEventArgs(false, ballId)); OnSwitch(false); } else { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); - Switch?.Invoke(this, new SwitchEventArgs(true, ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); + Switch?.Invoke(this, new SwitchEventArgs(true, ballId)); OnSwitch(true); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs index c9702dcd0..4a0e2ef9e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs @@ -38,10 +38,7 @@ public override void Bake(KickerComponent authoring) ZLow = authoring.Surface?.Height(authoring.Position) ?? authoring.PlayfieldHeight }); - AddComponent(new KickerCollisionData { - BallEntity = Entity.Null, - LastCapturedBallEntity = Entity.Null - }); + AddComponent(new KickerCollisionData()); // if (!Data.LegacyMode) { // // todo currently we don't allow non-legacy mode @@ -62,7 +59,7 @@ public override void Bake(KickerComponent authoring) } // register - GetComponentInParent().RegisterKicker(authoring, GetEntity()); + GetComponentInParent().RegisterKicker(authoring); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs index c68ea88fc..6a9eda33b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs @@ -34,7 +34,7 @@ internal static class KickerCollider public static void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, ref DynamicBuffer insideOfs, ref KickerCollisionData collData, in KickerStaticData staticData, in ColliderMeshData meshData, in CollisionEventData collEvent, - in Entity collEntity, in Entity ballEntity) + in int itemId, in int ballId) { // a previous ball already in kicker? if (collData.HasBall) { @@ -47,7 +47,7 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle var hitBit = collEvent.HitFlag; // check if kicker in ball's volume set - var isBallInside = BallData.IsInsideOf(in insideOfs, collEntity); + var isBallInside = BallData.IsInsideOf(in insideOfs, itemId); // New or (Hit && !Vol || UnHit && Vol) if (hitBit == isBallInside) { @@ -83,13 +83,13 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle ball.IsFrozen = !staticData.FallThrough; if (ball.IsFrozen) { - BallData.SetInsideOf(ref insideOfs, collEntity); // add kicker to ball's volume set - collData.BallEntity = ballEntity; - collData.LastCapturedBallEntity = ballEntity; + BallData.SetInsideOf(ref insideOfs, itemId); // add kicker to ball's volume set + collData.BallId = ballId; + collData.LastCapturedBallId = ballId; } // Fire the event before changing ball attributes, so scripters can get a useful ball state - events.Enqueue(new EventData(EventId.HitEventsHit, collEntity, ballEntity, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, itemId, ballId, true)); if (ball.IsFrozen || staticData.FallThrough) { // script may have unfrozen the ball @@ -108,15 +108,15 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle ball.Position = new float3(staticData.Center.x, staticData.Center.y, posZ); } else { - collData.BallEntity = Entity.Null; // make sure + collData.BallId = 0; // make sure } } } else { // exiting kickers volume // remove kicker to ball's volume set - BallData.SetOutsideOf(ref insideOfs, collEntity); - events.Enqueue(new EventData(EventId.HitEventsUnhit, collEntity, ballEntity, true)); + BallData.SetOutsideOf(ref insideOfs, itemId); + events.Enqueue(new EventData(EventId.HitEventsUnhit, itemId, ballId, true)); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs index 1c54bfac4..8a3ef7faa 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs @@ -51,7 +51,7 @@ public class KickerColliderComponent : ColliderComponent GetPhysicsMaterialData(scatterAngleDeg: Scatter); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new KickerApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new KickerApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionData.cs index facf1ec24..667f51c8f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionData.cs @@ -20,9 +20,9 @@ namespace VisualPinball.Unity { internal struct KickerCollisionData : IComponentData { - public Entity BallEntity; - public Entity LastCapturedBallEntity; - public bool HasBall => BallEntity != Entity.Null; + public int BallId; + public int LastCapturedBallId; + public bool HasBall => BallId != 0; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs index d895dbe6e..19c1cff90 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs @@ -56,7 +56,7 @@ public IRotatableComponent[] RotateWith { private Player _player; private KickerApi[] _kickers; - private (KickerApi kicker, float distance, float angle, Entity ballEntity)[] _ballEntities; + private (KickerApi kicker, float distance, float angle, int ballId)[] _ballEntities; private Dictionary _rotatingObjectDistances = new(); private static EntityManager EntityManager => World.DefaultGameObjectInjectionWorld.EntityManager; @@ -89,7 +89,7 @@ public void StartRotating() k, math.distance(pos, k.Position.xy), math.sign(pos.x - k.Position.x) * Vector2.Angle(k.Position.xy - pos, new float2(0f, -1f)), - k.BallEntity) + ballId: k.BallId) ).ToArray(); } @@ -109,22 +109,23 @@ public void UpdateRotation(float angleDeg) ); } - // rotate ball(s) in kicker(s) - foreach (var (kicker, distance, angle, ballEntity) in _ballEntities) { - if (!kicker.HasBall()) { - return; - } - var ballData = EntityManager.GetComponentData(ballEntity); - ballData.Position = new float3( - pos.x -distance * math.sin(math.radians(angleDeg + angle)), - pos.y -distance * math.cos(math.radians(angleDeg + angle)), - ballData.Position.z - ); - ballData.Velocity = float3.zero; - ballData.AngularMomentum = float3.zero; - - EntityManager.SetComponentData(ballEntity, ballData); - } + // fixme job + // // rotate ball(s) in kicker(s) + // foreach (var (kicker, distance, angle, ballEntity) in _ballEntities) { + // if (!kicker.HasBall()) { + // return; + // } + // var ballData = EntityManager.GetComponentData(ballEntity); + // ballData.Position = new float3( + // pos.x -distance * math.sin(math.radians(angleDeg + angle)), + // pos.y -distance * math.cos(math.radians(angleDeg + angle)), + // ballData.Position.z + // ); + // ballData.Velocity = float3.zero; + // ballData.AngularMomentum = float3.zero; + // + // EntityManager.SetComponentData(ballEntity, ballData); + // } } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs index eabe4b925..55a0afe67 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs @@ -16,7 +16,6 @@ using System; using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.MetalWireGuide; @@ -35,7 +34,7 @@ public class MetalWireGuideApi : CollidableApi public event EventHandler Hit; - internal MetalWireGuideApi(GameObject go, Entity entity, Player player) : base(go, entity, player) + internal MetalWireGuideApi(GameObject go, Player player) : base(go, player) { } @@ -64,9 +63,9 @@ void IApi.OnDestroy() { } - void IApiHittable.OnHit(Entity ballEntity, bool _) + void IApiHittable.OnHit(int ballId, bool _) { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs index 2eabbfae8..838a837e2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs @@ -25,7 +25,7 @@ public override void Bake(MetalWireGuideComponent authoring) base.Bake(authoring); // register - GetComponentInParent().RegisterMetalWireGuide(authoring, GetEntity()); + GetComponentInParent().RegisterMetalWireGuide(authoring); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs index f77892b28..53cba3fa2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs @@ -56,7 +56,7 @@ public class MetalWireGuideColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new MetalWireGuideApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new MetalWireGuideApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs index fb80e7291..ba00d514c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs @@ -25,7 +25,7 @@ namespace VisualPinball.Unity { public class PlayfieldApi : CollidableApi { - internal PlayfieldApi(GameObject go, Player player) : base(go, Player.PlayfieldEntity, player) + internal PlayfieldApi(GameObject go, Player player) : base(go, player) { } @@ -89,11 +89,11 @@ protected override void CreateColliders(List colliders, float margin) ColliderUtils.Generate3DPolyColliders(rgv3D, info, colliders); } - internal (PlaneCollider, PlaneCollider) CreateColliders() + internal (PlaneCollider, PlaneCollider) CreateColliders(int instanceId) { var info = new ColliderInfo { + ItemId = instanceId, ItemType = ItemType.Table, - Entity = Player.PlayfieldEntity, FireEvents = false, IsEnabled = true, Material = new PhysicsMaterialData { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs index 0d30b91cf..015342f1e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs @@ -55,13 +55,13 @@ public class PlayfieldColliderComponent : ColliderComponent GetPhysicsMaterialData(0, 0); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) + protected override IApiColliderGenerator InstantiateColliderApi(Player player) => new PlayfieldApi(gameObject, player); void ICollidableComponent.GetColliders(ref NativeList colliders) { var api = new PlayfieldApi(gameObject, GetComponent()); - var c = api.CreateColliders(); + var c = api.CreateColliders(GetInstanceID()); colliders.Add(c.Item1); colliders.Add(c.Item2); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs index 04f363c28..9f9b53c4e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs @@ -61,17 +61,17 @@ public class PlungerApi : CollidableApi(); // 0 = resting pos, 1 = pulled back - var movementData = EntityManager.GetComponentData(Entity); - movementData.AnalogPosition = pos; - EntityManager.SetComponentData(Entity, movementData); + // fixme job + // var pos = ctx.ReadValue(); // 0 = resting pos, 1 = pulled back + // var movementData = EntityManager.GetComponentData(Entity); + // movementData.AnalogPosition = pos; + // EntityManager.SetComponentData(Entity, movementData); } void IApi.OnInit(BallManager ballManager) @@ -89,55 +89,57 @@ void IApi.OnDestroy() public void PullBack() { - var collComponent = GameObject.GetComponent(); - if (!collComponent) { - return; - } - var movementData = EntityManager.GetComponentData(Entity); - var velocityData = EntityManager.GetComponentData(Entity); - - if (DoRetract) { - PlungerCommands.PullBackAndRetract(collComponent.SpeedPull, ref velocityData, ref movementData); - - } else { - PlungerCommands.PullBack(collComponent.SpeedPull, ref velocityData, ref movementData); - } - - EntityManager.SetComponentData(Entity, movementData); - EntityManager.SetComponentData(Entity, velocityData); + // fixme job + // var collComponent = GameObject.GetComponent(); + // if (!collComponent) { + // return; + // } + // var movementData = EntityManager.GetComponentData(Entity); + // var velocityData = EntityManager.GetComponentData(Entity); + // + // if (DoRetract) { + // PlungerCommands.PullBackAndRetract(collComponent.SpeedPull, ref velocityData, ref movementData); + // + // } else { + // PlungerCommands.PullBack(collComponent.SpeedPull, ref velocityData, ref movementData); + // } + // + // EntityManager.SetComponentData(Entity, movementData); + // EntityManager.SetComponentData(Entity, velocityData); } public void Fire() { - var collComponent = GameObject.GetComponent(); - if (!collComponent) { - return; - } - var movementData = EntityManager.GetComponentData(Entity); - var velocityData = EntityManager.GetComponentData(Entity); - var staticData = EntityManager.GetComponentData(Entity); - - // check for an auto plunger - if (collComponent.IsAutoPlunger) { - // Auto Plunger - this models a "Launch Ball" button or a - // ROM-controlled launcher, rather than a player-operated - // spring plunger. In a physical machine, this would be - // implemented as a solenoid kicker, so the amount of force - // is constant (modulo some mechanical randomness). Simulate - // this by triggering a release from the maximum retracted - // position. - PlungerCommands.Fire(1f, ref velocityData, ref movementData, in staticData); - - } else { - // Regular plunger - trigger a release from the current - // position, using the keyboard firing strength. - - var pos = (movementData.Position - staticData.FrameEnd) / (staticData.FrameStart - staticData.FrameEnd); - PlungerCommands.Fire(pos, ref velocityData, ref movementData, in staticData); - } - - EntityManager.SetComponentData(Entity, movementData); - EntityManager.SetComponentData(Entity, velocityData); + // fixme job + // var collComponent = GameObject.GetComponent(); + // if (!collComponent) { + // return; + // } + // var movementData = EntityManager.GetComponentData(Entity); + // var velocityData = EntityManager.GetComponentData(Entity); + // var staticData = EntityManager.GetComponentData(Entity); + // + // // check for an auto plunger + // if (collComponent.IsAutoPlunger) { + // // Auto Plunger - this models a "Launch Ball" button or a + // // ROM-controlled launcher, rather than a player-operated + // // spring plunger. In a physical machine, this would be + // // implemented as a solenoid kicker, so the amount of force + // // is constant (modulo some mechanical randomness). Simulate + // // this by triggering a release from the maximum retracted + // // position. + // PlungerCommands.Fire(1f, ref velocityData, ref movementData, in staticData); + // + // } else { + // // Regular plunger - trigger a release from the current + // // position, using the keyboard firing strength. + // + // var pos = (movementData.Position - staticData.FrameEnd) / (staticData.FrameStart - staticData.FrameEnd); + // PlungerCommands.Fire(pos, ref velocityData, ref movementData, in staticData); + // } + // + // EntityManager.SetComponentData(Entity, movementData); + // EntityManager.SetComponentData(Entity, velocityData); } IApiCoil IApiCoilDevice.Coil(string deviceItem) => Coil(deviceItem); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs index 0a121a1e8..a28210bd1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs @@ -44,7 +44,7 @@ public override void Bake(PlungerComponent authoring) var position = frameTop + restPos * frameLen; var info = new ColliderInfo { - Entity = GetEntity(), + ItemId = authoring.GetInstanceID(), FireEvents = true, IsEnabled = true, ItemType = ItemType.Plunger, @@ -99,7 +99,7 @@ public override void Bake(PlungerComponent authoring) }); // register at player - GetComponentInParent().RegisterPlunger(authoring, GetEntity(), authoring.analogPlungerAction); + GetComponentInParent().RegisterPlunger(authoring, authoring.analogPlungerAction); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs index 9ee87dab3..38412166e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs @@ -49,7 +49,7 @@ public PlungerCollider(PlungerComponent comp, PlungerColliderComponent collComp, JointBase1 = new LineZCollider(new float2(x2, y), zHeight, zHeight + Plunger.PlungerHeight, info); var frameEnd = comp.Position.y - collComp.Stroke; - Bounds = new ColliderBounds(_header.Entity, _header.Id, new Aabb( + Bounds = new ColliderBounds(_header.ItemId, _header.Id, new Aabb( x - 0.1f, x2 + 0.1f, frameEnd - 0.1f, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs index 8e03fcac7..2cf48ca92 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs @@ -57,7 +57,7 @@ public class PlungerColliderComponent : ColliderComponent GetPhysicsMaterialData(); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new PlungerApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new PlungerApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs index cd7399b4b..7fdc1cce7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs @@ -51,85 +51,86 @@ protected override void OnUpdate() var dTime = _simulateCycleSystemGroup.HitTime; var marker = PerfMarker; - Entities.WithName("PlungerDisplacementJob").ForEach((Entity entity, ref PlungerMovementData movementData, - ref PlungerColliderData colliderData, in PlungerStaticData staticData) => - { - marker.Begin(); - - // figure the travel distance - var dx = dTime * movementData.Speed; - - // figure the position change - movementData.Position += dx; - - // apply the travel limit - if (movementData.Position < movementData.TravelLimit) { - movementData.Position = movementData.TravelLimit; - } - - // if we're in firing mode and we've crossed the bounce position, reverse course - var relPos = (movementData.Position - staticData.FrameEnd) / staticData.FrameLen; - var bouncePos = staticData.RestPosition + movementData.FireBounce; - if (movementData.FireTimer != 0 && dTime != 0.0f && - (movementData.FireSpeed < 0.0f ? relPos <= bouncePos : relPos >= bouncePos)) - { - // stop at the bounce position - movementData.Position = staticData.FrameEnd + bouncePos * staticData.FrameLen; - - // reverse course at reduced speed - movementData.FireSpeed = -movementData.FireSpeed * 0.4f; - - // figure the new bounce as a fraction of the previous bounce - movementData.FireBounce *= -0.4f; - } - - // apply the travel limit (again) - if (movementData.Position < movementData.TravelLimit) { - movementData.Position = movementData.TravelLimit; - } - - // limit motion to the valid range - if (dTime != 0.0f) { - - if (movementData.Position < staticData.FrameEnd) { - movementData.Speed = 0.0f; - movementData.Position = staticData.FrameEnd; - - } else if (movementData.Position > staticData.FrameStart) { - movementData.Speed = 0.0f; - movementData.Position = staticData.FrameStart; - } - - // apply the travel limit (yet again) - if (movementData.Position < movementData.TravelLimit) { - movementData.Position = movementData.TravelLimit; - } - } - - // the travel limit applies to one displacement update only - reset it - movementData.TravelLimit = staticData.FrameEnd; - - // fire an Start/End of Stroke events, as appropriate - var strokeEventLimit = staticData.FrameLen / 50.0f; - var strokeEventHysteresis = strokeEventLimit * 2.0f; - if (movementData.StrokeEventsArmed && movementData.Position + dx > staticData.FrameStart - strokeEventLimit) { - events.Enqueue(new EventData(EventId.LimitEventsBos, entity, math.abs(movementData.Speed))); - movementData.StrokeEventsArmed = false; - - } else if (movementData.StrokeEventsArmed && movementData.Position + dx < staticData.FrameEnd + strokeEventLimit) { - events.Enqueue(new EventData(EventId.LimitEventsEos, entity, math.abs(movementData.Speed))); - movementData.StrokeEventsArmed = false; - - } else if (movementData.Position > staticData.FrameEnd + strokeEventHysteresis && movementData.Position < staticData.FrameStart - strokeEventHysteresis) { - // away from the limits - arm the stroke events - movementData.StrokeEventsArmed = true; - } - - // update the display - UpdateCollider(movementData.Position, ref colliderData); - - marker.End(); - }).Run(); + // fixme job + // Entities.WithName("PlungerDisplacementJob").ForEach((Entity entity, ref PlungerMovementData movementData, + // ref PlungerColliderData colliderData, in PlungerStaticData staticData) => + // { + // marker.Begin(); + // + // // figure the travel distance + // var dx = dTime * movementData.Speed; + // + // // figure the position change + // movementData.Position += dx; + // + // // apply the travel limit + // if (movementData.Position < movementData.TravelLimit) { + // movementData.Position = movementData.TravelLimit; + // } + // + // // if we're in firing mode and we've crossed the bounce position, reverse course + // var relPos = (movementData.Position - staticData.FrameEnd) / staticData.FrameLen; + // var bouncePos = staticData.RestPosition + movementData.FireBounce; + // if (movementData.FireTimer != 0 && dTime != 0.0f && + // (movementData.FireSpeed < 0.0f ? relPos <= bouncePos : relPos >= bouncePos)) + // { + // // stop at the bounce position + // movementData.Position = staticData.FrameEnd + bouncePos * staticData.FrameLen; + // + // // reverse course at reduced speed + // movementData.FireSpeed = -movementData.FireSpeed * 0.4f; + // + // // figure the new bounce as a fraction of the previous bounce + // movementData.FireBounce *= -0.4f; + // } + // + // // apply the travel limit (again) + // if (movementData.Position < movementData.TravelLimit) { + // movementData.Position = movementData.TravelLimit; + // } + // + // // limit motion to the valid range + // if (dTime != 0.0f) { + // + // if (movementData.Position < staticData.FrameEnd) { + // movementData.Speed = 0.0f; + // movementData.Position = staticData.FrameEnd; + // + // } else if (movementData.Position > staticData.FrameStart) { + // movementData.Speed = 0.0f; + // movementData.Position = staticData.FrameStart; + // } + // + // // apply the travel limit (yet again) + // if (movementData.Position < movementData.TravelLimit) { + // movementData.Position = movementData.TravelLimit; + // } + // } + // + // // the travel limit applies to one displacement update only - reset it + // movementData.TravelLimit = staticData.FrameEnd; + // + // // fire an Start/End of Stroke events, as appropriate + // var strokeEventLimit = staticData.FrameLen / 50.0f; + // var strokeEventHysteresis = strokeEventLimit * 2.0f; + // if (movementData.StrokeEventsArmed && movementData.Position + dx > staticData.FrameStart - strokeEventLimit) { + // events.Enqueue(new EventData(EventId.LimitEventsBos, entity, math.abs(movementData.Speed))); + // movementData.StrokeEventsArmed = false; + // + // } else if (movementData.StrokeEventsArmed && movementData.Position + dx < staticData.FrameEnd + strokeEventLimit) { + // events.Enqueue(new EventData(EventId.LimitEventsEos, entity, math.abs(movementData.Speed))); + // movementData.StrokeEventsArmed = false; + // + // } else if (movementData.Position > staticData.FrameEnd + strokeEventHysteresis && movementData.Position < staticData.FrameStart - strokeEventHysteresis) { + // // away from the limits - arm the stroke events + // movementData.StrokeEventsArmed = true; + // } + // + // // update the display + // UpdateCollider(movementData.Position, ref colliderData); + // + // marker.End(); + // }).Run(); // dequeue events while (_eventQueue.TryDequeue(out var eventData)) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs index 7fd8a4974..bbfdf37a3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs @@ -39,16 +39,17 @@ protected override void OnUpdate() { var marker = PerfMarker; - Entities.WithoutBurst().WithName("PlungerTransformationJob").ForEach((Entity entity, in PlungerAnimationData animationData) => { - - marker.Begin(); - - foreach (var skinnedMeshRenderer in _player.PlungerSkinnedMeshRenderers[entity]) { - skinnedMeshRenderer.SetBlendShapeWeight(0, animationData.Position); - } - marker.End(); - - }).Run(); + // fixme job + // Entities.WithoutBurst().WithName("PlungerTransformationJob").ForEach((Entity entity, in PlungerAnimationData animationData) => { + // + // marker.Begin(); + // + // foreach (var skinnedMeshRenderer in _player.PlungerSkinnedMeshRenderers[entity]) { + // skinnedMeshRenderer.SetBlendShapeWeight(0, animationData.Position); + // } + // marker.End(); + // + // }).Run(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs index ae92367b7..75847cd7c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs @@ -16,7 +16,6 @@ using System; using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Primitive; @@ -35,7 +34,7 @@ public class PrimitiveApi : CollidableApi public event EventHandler Hit; - internal PrimitiveApi(GameObject go, Entity entity, Player player) : base(go, entity, player) + internal PrimitiveApi(GameObject go, Player player) : base(go, player) { } @@ -64,9 +63,9 @@ void IApi.OnDestroy() { } - void IApiHittable.OnHit(Entity ballEntity, bool _) + void IApiHittable.OnHit(int ballId, bool _) { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs index 846fd42c9..76d2ed249 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs @@ -25,7 +25,7 @@ public override void Bake(PrimitiveComponent authoring) base.Bake(authoring); // register - GetComponentInParent().RegisterPrimitive(authoring, GetEntity()); + GetComponentInParent().RegisterPrimitive(authoring); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs index cb77d793d..dfecc442e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs @@ -61,7 +61,7 @@ public class PrimitiveColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new PrimitiveApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new PrimitiveApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs index 93f5098e6..b5bbfa660 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs @@ -16,12 +16,12 @@ using System; using System.Collections.Generic; -using Unity.Entities; using UnityEngine; +using VisualPinball.Engine.VPT.Ramp; namespace VisualPinball.Unity { - public class RampApi : CollidableApi, IApi, IApiHittable + public class RampApi : CollidableApi, IApi, IApiHittable { /// /// Event emitted when the table is started. @@ -33,7 +33,7 @@ public class RampApi : CollidableApi public event EventHandler Hit; - internal RampApi(GameObject go, Entity entity, Player player) : base(go, entity, player) + internal RampApi(GameObject go, Player player) : base(go, player) { } @@ -45,9 +45,9 @@ void IApi.OnInit(BallManager ballManager) Init?.Invoke(this, EventArgs.Empty); } - public void OnHit(Entity ballEntity, bool isUnHit = false) + public void OnHit(int ballId, bool isUnHit = false) { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); } void IApi.OnDestroy() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs index dd82f8290..5d12b8ba4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs @@ -24,7 +24,7 @@ public override void Bake(RampComponent authoring) { base.Bake(authoring); - GetComponentInParent().RegisterRamp(authoring, GetEntity()); + GetComponentInParent().RegisterRamp(authoring); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs index 203c1d124..2f4eb7366 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs @@ -61,7 +61,7 @@ public class RampColliderComponent : ColliderComponent #endregion public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(Elasticity, friction: Friction, scatterAngleDeg: Scatter, overwrite: OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new RampApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new RampApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs index ea61d2ada..6586a5c05 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs @@ -16,7 +16,6 @@ using System; using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Rubber; @@ -35,7 +34,7 @@ public class RubberApi : CollidableApi public event EventHandler Hit; - internal RubberApi(GameObject go, Entity entity, Player player) : base(go, entity, player) + internal RubberApi(GameObject go, Player player) : base(go, player) { } @@ -64,9 +63,9 @@ void IApi.OnDestroy() { } - void IApiHittable.OnHit(Entity ballEntity, bool _) + void IApiHittable.OnHit(int ballId, bool _) { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs index 7accdc5ae..f6d7d9d2f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs @@ -25,7 +25,7 @@ public override void Bake(RubberComponent authoring) base.Bake(authoring); // register - GetComponentInParent().RegisterRubber(authoring, GetEntity()); + GetComponentInParent().RegisterRubber(authoring); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs index 90bfd17eb..7443ccd4c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs @@ -56,7 +56,7 @@ public class RubberColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new RubberApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new RubberApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs index 7c9d57203..0ea616146 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs @@ -65,8 +65,7 @@ public class SpinnerApi : CollidableApi public event EventHandler Switch; - public SpinnerApi(GameObject go, Entity entity, Player player) - : base(go, entity, player) + public SpinnerApi(GameObject go, Player player) : base(go, player) { } @@ -108,7 +107,7 @@ void IApi.OnDestroy() void IApiSpinnable.OnSpin() { Spin?.Invoke(this, EventArgs.Empty); - Switch?.Invoke(this, new SwitchEventArgs(true, Entity.Null)); + Switch?.Invoke(this, new SwitchEventArgs(true)); OnSwitch(true); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs index 3830a63a7..ef596e9b0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs @@ -48,7 +48,7 @@ public override void Bake(SpinnerComponent authoring) } // register - GetComponentInParent().RegisterSpinner(authoring, GetEntity()); + GetComponentInParent().RegisterSpinner(authoring); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs index a0a7018e0..5b1431ce1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs @@ -35,7 +35,7 @@ public class SpinnerColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new SpinnerApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new SpinnerApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs index 9095c59ee..157513325 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs @@ -55,75 +55,76 @@ protected override void OnUpdate() var dTime = _simulateCycleSystemGroup.HitTime; var marker = PerfMarker; - Entities - .WithName("SpinnerDisplacementJob") - .ForEach((Entity entity, ref SpinnerMovementData movementData, in SpinnerStaticData data) => { - - marker.Begin(); - - // those are already converted to radian during authoring. - var angleMin = data.AngleMin; - var angleMax = data.AngleMax; - - // blocked spinner, limited motion spinner - if (data.AngleMin != data.AngleMax) { - - movementData.Angle += movementData.AngleSpeed * dTime; - - if (movementData.Angle > angleMax) { - movementData.Angle = angleMax; - - // send EOS event - events.Enqueue(new EventData(EventId.LimitEventsEos, entity, math.abs(math.degrees(movementData.AngleSpeed)))); - - if (movementData.AngleSpeed > 0.0f) { - movementData.AngleSpeed *= -0.005f - data.Elasticity; - } - } - - if (movementData.Angle < angleMin) { - movementData.Angle = angleMin; - - // send Park event - events.Enqueue(new EventData(EventId.LimitEventsBos, entity, math.abs(math.degrees(movementData.AngleSpeed)))); - - if (movementData.AngleSpeed < 0.0f) { - movementData.AngleSpeed *= -0.005f - data.Elasticity; - } - } - - } else { - - var target = movementData.AngleSpeed > 0.0f - ? movementData.Angle < math.PI ? math.PI : 3.0f * math.PI - : movementData.Angle < math.PI ? -math.PI : math.PI; - - movementData.Angle += movementData.AngleSpeed * dTime; - - if (movementData.AngleSpeed > 0.0f) { - - if (movementData.Angle > target) { - events.Enqueue(new EventData(EventId.SpinnerEventsSpin, entity, true)); - } - - } else { - if (movementData.Angle < target) { - events.Enqueue(new EventData(EventId.SpinnerEventsSpin, entity, true)); - } - } - - while (movementData.Angle > 2.0f * math.PI) { - movementData.Angle -= 2.0f * math.PI; - } - - while (movementData.Angle < 0.0f) { - movementData.Angle += 2.0f * math.PI; - } - } - - marker.End(); - - }).Run(); + // fixme job + // Entities + // .WithName("SpinnerDisplacementJob") + // .ForEach((Entity entity, ref SpinnerMovementData movementData, in SpinnerStaticData data) => { + // + // marker.Begin(); + // + // // those are already converted to radian during authoring. + // var angleMin = data.AngleMin; + // var angleMax = data.AngleMax; + // + // // blocked spinner, limited motion spinner + // if (data.AngleMin != data.AngleMax) { + // + // movementData.Angle += movementData.AngleSpeed * dTime; + // + // if (movementData.Angle > angleMax) { + // movementData.Angle = angleMax; + // + // // send EOS event + // events.Enqueue(new EventData(EventId.LimitEventsEos, entity, math.abs(math.degrees(movementData.AngleSpeed)))); + // + // if (movementData.AngleSpeed > 0.0f) { + // movementData.AngleSpeed *= -0.005f - data.Elasticity; + // } + // } + // + // if (movementData.Angle < angleMin) { + // movementData.Angle = angleMin; + // + // // send Park event + // events.Enqueue(new EventData(EventId.LimitEventsBos, entity, math.abs(math.degrees(movementData.AngleSpeed)))); + // + // if (movementData.AngleSpeed < 0.0f) { + // movementData.AngleSpeed *= -0.005f - data.Elasticity; + // } + // } + // + // } else { + // + // var target = movementData.AngleSpeed > 0.0f + // ? movementData.Angle < math.PI ? math.PI : 3.0f * math.PI + // : movementData.Angle < math.PI ? -math.PI : math.PI; + // + // movementData.Angle += movementData.AngleSpeed * dTime; + // + // if (movementData.AngleSpeed > 0.0f) { + // + // if (movementData.Angle > target) { + // events.Enqueue(new EventData(EventId.SpinnerEventsSpin, entity, true)); + // } + // + // } else { + // if (movementData.Angle < target) { + // events.Enqueue(new EventData(EventId.SpinnerEventsSpin, entity, true)); + // } + // } + // + // while (movementData.Angle > 2.0f * math.PI) { + // movementData.Angle -= 2.0f * math.PI; + // } + // + // while (movementData.Angle < 0.0f) { + // movementData.Angle += 2.0f * math.PI; + // } + // } + // + // marker.End(); + // + // }).Run(); // dequeue events while (_eventQueue.TryDequeue(out var eventData)) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs index 41f5a8f4f..8dcf0c339 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs @@ -38,16 +38,17 @@ protected override void OnStartRunning() protected override void OnUpdate() { - var marker = PerfMarker; - Entities.WithoutBurst().WithName("SpinnerMovementJob").ForEach((Entity entity, in SpinnerMovementData movementData) => { - - marker.Begin(); - - _player.SpinnerPlateTransforms[entity].localRotation = quaternion.RotateX(-movementData.Angle); - - marker.End(); - - }).Run(); + // fixme job + // var marker = PerfMarker; + // Entities.WithoutBurst().WithName("SpinnerMovementJob").ForEach((Entity entity, in SpinnerMovementData movementData) => { + // + // marker.Begin(); + // + // _player.SpinnerPlateTransforms[entity].localRotation = quaternion.RotateX(-movementData.Angle); + // + // marker.End(); + // + // }).Run(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs index aeb7b50af..4caf0c53b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs @@ -15,10 +15,9 @@ // along with this program. If not, see . using System; -using Logger = NLog.Logger; using NLog; using UnityEngine; -using Unity.Entities; +using Logger = NLog.Logger; namespace VisualPinball.Unity { @@ -64,7 +63,7 @@ void IApi.OnInit(BallManager ballManager) private void OnSlingshot(object sender, EventArgs e) { - Switch?.Invoke(this, new SwitchEventArgs(true, Entity.Null)); + Switch?.Invoke(this, new SwitchEventArgs(true)); OnSwitch(true); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs index fef9b2063..d63125844 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs @@ -16,12 +16,12 @@ using System; using System.Collections.Generic; -using Unity.Entities; using UnityEngine; +using VisualPinball.Engine.VPT.Surface; namespace VisualPinball.Unity { - public class SurfaceApi : CollidableApi, + public class SurfaceApi : CollidableApi, IApi, IApiHittable, IApiSlingshot { /// @@ -39,7 +39,7 @@ public class SurfaceApi : CollidableApi public event EventHandler Slingshot; - internal SurfaceApi(GameObject go, Entity entity, Player player) : base(go, entity, player) + internal SurfaceApi(GameObject go, Player player) : base(go, player) { } @@ -70,12 +70,12 @@ void IApi.OnDestroy() { } - void IApiHittable.OnHit(Entity ballEntity, bool _) + void IApiHittable.OnHit(int ballId, bool _) { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); } - public void OnSlingshot(Entity ballEntity) + public void OnSlingshot(int ballId) { Slingshot?.Invoke(this, EventArgs.Empty); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs index 0e7cbf8ad..bb69b7e50 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs @@ -33,7 +33,7 @@ public override void Bake(SurfaceComponent authoring) }); } - GetComponentInParent().RegisterSurface(authoring, GetEntity()); + GetComponentInParent().RegisterSurface(authoring); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs index 17fa8338c..7bf9ccec5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs @@ -68,7 +68,7 @@ public class SurfaceColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new SurfaceApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new SurfaceApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs index 10370b4aa..d509836f2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs @@ -16,7 +16,6 @@ using System; using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Trigger; @@ -45,8 +44,8 @@ public class TriggerApi : CollidableApi public event EventHandler Switch; - internal TriggerApi(GameObject go, Entity entity, Player player) - : base(go, entity, player) + internal TriggerApi(GameObject go, Player player) + : base(go, player) { } @@ -88,16 +87,16 @@ void IApi.OnDestroy() { } - void IApiHittable.OnHit(Entity ballEntity, bool isUnHit) + void IApiHittable.OnHit(int ballId, bool isUnHit) { if (isUnHit) { - UnHit?.Invoke(this, new HitEventArgs(ballEntity)); - Switch?.Invoke(this, new SwitchEventArgs(false, ballEntity)); + UnHit?.Invoke(this, new HitEventArgs(ballId)); + Switch?.Invoke(this, new SwitchEventArgs(false, ballId)); OnSwitch(false); } else { - Hit?.Invoke(this, new HitEventArgs(ballEntity)); - Switch?.Invoke(this, new SwitchEventArgs(true, ballEntity)); + Hit?.Invoke(this, new HitEventArgs(ballId)); + Switch?.Invoke(this, new SwitchEventArgs(true, ballId)); OnSwitch(true); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs index 124866ec7..68b126239 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs @@ -39,7 +39,7 @@ public override void Bake(TriggerComponent authoring) } // register - GetComponentInParent().RegisterTrigger(authoring, GetEntity()); + GetComponentInParent().RegisterTrigger(authoring); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs index e71e85920..aaac44852 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs @@ -25,22 +25,22 @@ internal static class TriggerCollider { public static void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, ref CollisionEventData collEvent, ref DynamicBuffer insideOfs, - ref TriggerAnimationData animationData, in Entity ballEntity, in Collider coll) + ref TriggerAnimationData animationData, in int ballId, in Collider coll) { - var insideOf = BallData.IsInsideOf(in insideOfs, coll.Entity); + var insideOf = BallData.IsInsideOf(in insideOfs, coll.ItemId); if (collEvent.HitFlag == insideOf) { // Hit == NotAlreadyHit ball.Position += PhysicsConstants.StaticTime * ball.Velocity; // move ball slightly forward if (!insideOf) { - BallData.SetInsideOf(ref insideOfs, coll.Entity); + BallData.SetInsideOf(ref insideOfs, coll.ItemId); animationData.HitEvent = true; - events.Enqueue(new EventData(EventId.HitEventsHit, coll.Entity, ballEntity, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, coll.ItemId, ballId, true)); } else { - BallData.SetOutsideOf(ref insideOfs, coll.Entity); + BallData.SetOutsideOf(ref insideOfs, coll.ItemId); animationData.UnHitEvent = true; - events.Enqueue(new EventData(EventId.HitEventsUnhit, coll.Entity, ballEntity, true)); + events.Enqueue(new EventData(EventId.HitEventsUnhit, coll.ItemId, ballId, true)); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs index ab6f283de..26e9f2f73 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs @@ -39,7 +39,7 @@ public class TriggerColliderComponent : ColliderComponent GetPhysicsMaterialData(); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, Entity entity) - => new TriggerApi(gameObject, entity, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player) + => new TriggerApi(gameObject, player); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs index 436ad0e08..90d3cc008 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs @@ -42,22 +42,23 @@ protected override void OnUpdate() { var marker = PerfMarker; - Entities.WithoutBurst().WithName("TriggerMovementJob").ForEach((Entity entity, in TriggerMovementData data) => { - - marker.Begin(); - - var transform = _player.TriggerTransforms[entity]; - if (!_initialOffset.ContainsKey(entity)) { - _initialOffset[entity] = transform.position.y; - } - - var worldPos = transform.position; - worldPos.y = _initialOffset[entity] + VisualPinball.Unity.Physics.ScaleToWorld(data.HeightOffset); - transform.position = worldPos; - - marker.End(); - - }).Run(); + // fixme job + // Entities.WithoutBurst().WithName("TriggerMovementJob").ForEach((Entity entity, in TriggerMovementData data) => { + // + // marker.Begin(); + // + // var transform = _player.TriggerTransforms[entity]; + // if (!_initialOffset.ContainsKey(entity)) { + // _initialOffset[entity] = transform.position.y; + // } + // + // var worldPos = transform.position; + // worldPos.y = _initialOffset[entity] + VisualPinball.Unity.Physics.ScaleToWorld(data.HeightOffset); + // transform.position = worldPos; + // + // marker.End(); + // + // }).Run(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs index cd025398b..bba383824 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs @@ -291,7 +291,7 @@ private void OnEntry(object sender, SwitchEventArgs args) if (_drainSwitch is KickerApi kickerApi) { kickerApi.DestroyBall(); } else { - BallManager.DestroyEntity(args.BallEntity); + BallManager.DestroyEntity(args.BallId); } DrainBall(); From 8f8ab469933258fa3d4457270011afd246b7738f Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 12 Feb 2023 23:40:53 +0100 Subject: [PATCH 034/159] jobs: Add static counts. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 28 +++++- .../Game/PhysicsStaticNarrowPhase.cs | 4 +- .../Physics/Collision/CollisionEventData.cs | 14 +-- .../Physics/Collision/ContactSystem.cs | 2 +- .../Collision/DynamicCollisionSystem.cs | 64 +++++++------- .../Collision/DynamicNarrowPhaseSystem.cs | 85 ++++++++++--------- 6 files changed, 110 insertions(+), 87 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index cc360fc2b..8b73ac032 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -17,6 +17,7 @@ using System; using NativeTrees; using Unity.Collections; +using VisualPinball.Engine.Common; namespace VisualPinball.Unity { @@ -33,6 +34,9 @@ public PhysicsCycle(Allocator a) internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree octree, ref NativeList balls) { + + var staticCounts = PhysicsConstants.StaticCnts; + while (dTime > 0) { var hitTime = dTime; // begin time search from now ... until delta ends @@ -59,12 +63,15 @@ internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree -1 || ColliderEntity != Entity.Null; + return ColliderId > -1 || BallId != 0; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs index 27bd36f4d..5656f2c6d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs @@ -98,7 +98,7 @@ protected override void OnUpdate() } } - } else if (collEvent.ColliderEntity != Entity.Null) { // collide with ball + } else if (collEvent.BallId != 0) { // collide with ball // todo move ball friction into some data component BallCollider.HandleStaticContact(ref ball, in collEvent, 0.3f, hitTime, in gravity); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs index d25fe1f2b..9a67d232f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs @@ -40,37 +40,39 @@ protected override void OnUpdate() var balls = GetComponentLookup(); var collEvents = GetComponentLookup(true); - Entities - .WithName("DynamicCollisionJob") - .WithNativeDisableParallelForRestriction(balls) - .WithReadOnly(collEvents) - .ForEach((ref BallData ball, ref CollisionEventData collEvent) => { - - // pick "other" ball - ref var otherEntity = ref collEvent.ColliderEntity; - - // find balls with hit objects and minimum time - if (otherEntity != Entity.Null && collEvent.HitTime <= hitTime) { - - marker.Begin(); - - var otherBall = balls[otherEntity]; - var otherCollEvent = collEvents[otherEntity]; - - // now collision, contact and script reactions on active ball (object)+++++++++ - - //this.activeBall = ball; // For script that wants the ball doing the collision - - if (BallCollider.Collide(ref otherBall, ref ball,in otherCollEvent, in collEvent, swapBallCollisionHandling)) { - balls[otherEntity] = otherBall; - } - - // remove trial hit object pointer - collEvent.ClearCollider(); - - marker.End(); - } - }).Run(); + // fixme job + // Entities + // .WithName("DynamicCollisionJob") + // .WithNativeDisableParallelForRestriction(balls) + // .WithReadOnly(collEvents) + // .ForEach((ref BallData ball, ref CollisionEventData collEvent) => { + // + // + // // pick "other" ball + // ref var otherId = ref collEvent.BallId; + // + // // find balls with hit objects and minimum time + // if (otherId != 0 && collEvent.HitTime <= hitTime) { + // + // marker.Begin(); + // + // var otherBall = balls[otherId]; + // var otherCollEvent = collEvents[otherId]; + // + // // now collision, contact and script reactions on active ball (object)+++++++++ + // + // //this.activeBall = ball; // For script that wants the ball doing the collision + // + // if (BallCollider.Collide(ref otherBall, ref ball,in otherCollEvent, in collEvent, swapBallCollisionHandling)) { + // balls[otherId] = otherBall; + // } + // + // // remove trial hit object pointer + // collEvent.ClearCollider(); + // + // marker.End(); + // } + // }).Run(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs index 935f81aee..9cb9e6af7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs @@ -39,48 +39,49 @@ protected override void OnUpdate() var marker = PerfMarker; - Entities - .WithName("DynamicNarrowPhaseJob") - .WithReadOnly(contacts) - .WithNativeDisableParallelForRestriction(ballsLookup) - .ForEach((Entity ballEntity, ref BallData ball, ref CollisionEventData collEvent, - in DynamicBuffer overlappingEntities) => - { - // don't play with frozen balls - if (ball.IsFrozen) { - return; - } - - marker.Begin(); - - //var contacts = contactsLookup[collDataEntity]; - for (var k = 0; k < overlappingEntities.Length; k++) { - var collBallEntity = overlappingEntities[k].Value; - var collBall = ballsLookup[collBallEntity]; - - var newCollEvent = new CollisionEventData(); - var newTime = BallCollider.HitTest(ref newCollEvent, ref ball, in collBall, collEvent.HitTime); - var validHit = newTime >= 0 && !Math.Sign(newTime) && newTime <= collEvent.HitTime; - - if (newCollEvent.IsContact || validHit) { - newCollEvent.SetCollider(collBallEntity); - newCollEvent.HitTime = newTime; - if (newCollEvent.IsContact) { - contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); - - } else { // if (validhit) - collEvent = newCollEvent; - } - } - - // write back - ballsLookup[collBallEntity] = collBall; - } - - marker.End(); - - } - ).Run(); + // fixme job + // Entities + // .WithName("DynamicNarrowPhaseJob") + // .WithReadOnly(contacts) + // .WithNativeDisableParallelForRestriction(ballsLookup) + // .ForEach((Entity ballEntity, ref BallData ball, ref CollisionEventData collEvent, + // in DynamicBuffer overlappingEntities) => + // { + // // don't play with frozen balls + // if (ball.IsFrozen) { + // return; + // } + // + // marker.Begin(); + // + // //var contacts = contactsLookup[collDataEntity]; + // for (var k = 0; k < overlappingEntities.Length; k++) { + // var collBallEntity = overlappingEntities[k].Value; + // var collBall = ballsLookup[collBallEntity]; + // + // var newCollEvent = new CollisionEventData(); + // var newTime = BallCollider.HitTest(ref newCollEvent, ref ball, in collBall, collEvent.HitTime); + // var validHit = newTime >= 0 && !Math.Sign(newTime) && newTime <= collEvent.HitTime; + // + // if (newCollEvent.IsContact || validHit) { + // newCollEvent.SetCollider(collBallEntity); + // newCollEvent.HitTime = newTime; + // if (newCollEvent.IsContact) { + // contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); + // + // } else { // if (validhit) + // collEvent = newCollEvent; + // } + // } + // + // // write back + // ballsLookup[collBallEntity] = collBall; + // } + // + // marker.End(); + // + // } + // ).Run(); } } } From 34d9e64505cdffe1fb2d24852f3b7353cfb9f651 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 17 Feb 2023 23:49:43 +0100 Subject: [PATCH 035/159] jobs: Add ball displacement. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 9 +- .../VPT/Ball/BallDisplacementPhysics.cs | 92 +++++++++++++++++++ .../VPT/Ball/BallDisplacementPhysics.cs.meta | 3 + 3 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 8b73ac032..4a24173bc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -18,6 +18,7 @@ using NativeTrees; using Unity.Collections; using VisualPinball.Engine.Common; +using VisualPinballUnity; namespace VisualPinball.Unity { @@ -70,8 +71,12 @@ internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree. + +using Unity.Entities; +using Unity.Mathematics; +using Unity.Profiling; +using UnityEngine; +using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; + +namespace VisualPinballUnity +{ + internal static class BallDisplacementPhysics + { + private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallDisplacementPhysics"); + + internal static void UpdateDisplacements(this BallData ball, float dTime) + { + PerfMarker.Begin(); + + ball.Position += ball.Velocity * dTime; + + + //Logger.Debug($"Ball {ball.Id} Position = {ball.Position}"); + + var inertia = ball.Inertia; + var mat3 = CreateSkewSymmetric(ball.AngularMomentum / inertia); + var addedOrientation = math.mul(ball.BallOrientation, mat3); + addedOrientation *= dTime; + + ball.BallOrientation += addedOrientation; + + // do the same for Unity's ball Orientation (where z (and z only rotation) has to be flipped), + // which (maybe??) can't be done after skew matrix operations (or we don't know how)) + // If we flip an exis in the matrix, we always flip two rotations. + var AngMomFlippedZ = new float3(ball.AngularMomentum.x, ball.AngularMomentum.y, -ball.AngularMomentum.z); + mat3 = CreateSkewSymmetric(AngMomFlippedZ / inertia); + addedOrientation = math.mul(ball.BallOrientationForUnity, mat3); + addedOrientation *= dTime; + + ball.BallOrientationForUnity += addedOrientation; + + VPOrthonormalize(ref ball.BallOrientation); + VPOrthonormalize(ref ball.BallOrientationForUnity); + + PerfMarker.End(); + } + + private static void VPOrthonormalize(ref float3x3 orientation) + { + Vector3 vX = new Vector3(orientation.c0.x, orientation.c1.x, orientation.c2.x); + Vector3 vY = new Vector3(orientation.c0.y, orientation.c1.y, orientation.c2.y); + Vector3 vZ = Vector3.Cross(vX, vY); + vX = Vector3.Normalize(vX); + vZ = Vector3.Normalize(vZ); + vY = Vector3.Cross(vZ, vX); + + orientation.c0.x = vX.x; + orientation.c0.y = vY.x; + orientation.c0.z = vZ.x; + orientation.c1.x = vX.y; + orientation.c1.y = vY.y; + orientation.c1.z = vZ.y; + orientation.c2.x = vX.z; + orientation.c2.y = vY.z; + orientation.c2.z = vZ.z; + + } + + private static float3x3 CreateSkewSymmetric(in float3 pv3D) + { + return new float3x3( + 0, -pv3D.z, pv3D.y, + pv3D.z, 0, -pv3D.x, + -pv3D.y, pv3D.x, 0 + ); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs.meta new file mode 100644 index 000000000..2e095d05a --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3f76a7dfe56c4f1981dce51d4dd4a160 +timeCreated: 1679006624 \ No newline at end of file From d340204df2d4dcd431c64c5bfa71b9296de65751 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 18 Feb 2023 22:00:50 +0100 Subject: [PATCH 036/159] jobs: Add static collision. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 15 ++++-- .../VisualPinball.Unity/Game/PhysicsState.cs | 4 ++ .../Game/PhysicsStaticCollision.cs | 48 +++++++++++++++++++ .../Game/PhysicsStaticCollision.cs.meta | 3 ++ .../Game/PhysicsStaticNarrowPhase.cs | 2 +- .../Physics/Collision/CollisionEventData.cs | 8 ++++ 6 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 4a24173bc..6c1ffe0e7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -72,17 +72,24 @@ internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree. +using Unity.Mathematics; using VisualPinball.Engine.Common; namespace VisualPinball.Unity @@ -24,11 +25,14 @@ public struct PhysicsState public ulong CurPhysicsFrameTime; public ulong NextPhysicsFrameTime; + public Random Random; + public PhysicsState(ulong startTimeUsec) : this() { StartTimeUsec = startTimeUsec; CurPhysicsFrameTime = StartTimeUsec; NextPhysicsFrameTime = StartTimeUsec + PhysicsConstants.PhysicsStepTime; + Random = new Random((uint)UnityEngine.Random.Range(1, 100000)); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs new file mode 100644 index 000000000..9272ac169 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -0,0 +1,48 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable ConvertIfStatementToSwitchStatement + +using Unity.Mathematics; +using Unity.Profiling; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class PhysicsStaticCollision + { + private static readonly ProfilerMarker PerfMarker = new("PhysicsStaticCollision"); + + internal static void Collide(float hitTime, ref BallData ball, ref Random random) + { + + // find balls with hit objects and minimum time + if (ball.CollisionEvent.ColliderId < 0 || ball.CollisionEvent.HitTime > hitTime) { + return; + } + + PerfMarker.Begin(); + + ball.CollisionEvent.Collider.Collide(ref ball, in ball.CollisionEvent, ref random); + + // remove trial hit object pointer + ball.CollisionEvent.ClearCollider(); + + + PerfMarker.End(); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs.meta new file mode 100644 index 000000000..de996f8c7 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: af1a4f63b59246f2be6138582acfa192 +timeCreated: 1679007108 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index e04016062..00bad7a74 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -61,7 +61,7 @@ private static void SaveCollisions(ref BallData ball, ref CollisionEventData new var validHit = newTime >= 0f && !Math.Sign(newTime) && newTime <= ball.CollisionEvent.HitTime; if (newCollEvent.IsContact || validHit) { - newCollEvent.SetCollider(coll.Id); + newCollEvent.SetCollider(coll); newCollEvent.HitTime = newTime; if (newCollEvent.IsContact) { contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs index f1beb79f8..8904ce82c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs @@ -29,9 +29,17 @@ internal struct CollisionEventData : IComponentData public float HitOrgNormalVelocity; public bool IsContact; + public PlaneCollider Collider; public int ColliderId; public int BallId; + public void SetCollider(PlaneCollider collider) + { + Collider = collider; + ColliderId = collider.Id; + BallId = 0; + } + public void SetCollider(int colliderId) { ColliderId = colliderId; From 2c285c757a4b0eed540621a5a4a3f86261f1de46 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 19 Feb 2023 16:42:20 +0100 Subject: [PATCH 037/159] jobs: Add contact handling. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 8 ++++++-- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 2 +- .../VisualPinball.Unity/Game/PhysicsState.cs | 4 +++- .../VisualPinball.Unity/Physics/Collider/PlaneCollider.cs | 2 ++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 6c1ffe0e7..a9e56778f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -89,9 +89,13 @@ internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree(1, Allocator.Persistent); - _physicsState[0] = new PhysicsState(NowUsec); + _physicsState[0] = new PhysicsState(NowUsec, GetComponent()); // create static octree var sw = Stopwatch.StartNew(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 82a8eca5b..d84b6df00 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -21,18 +21,20 @@ namespace VisualPinball.Unity { public struct PhysicsState { + public readonly float3 Gravity; public readonly ulong StartTimeUsec; public ulong CurPhysicsFrameTime; public ulong NextPhysicsFrameTime; public Random Random; - public PhysicsState(ulong startTimeUsec) : this() + public PhysicsState(ulong startTimeUsec, Player player) : this() { StartTimeUsec = startTimeUsec; CurPhysicsFrameTime = StartTimeUsec; NextPhysicsFrameTime = StartTimeUsec + PhysicsConstants.PhysicsStepTime; Random = new Random((uint)UnityEngine.Random.Range(1, 100000)); + Gravity = player.Gravity; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index 909221448..2d91bc3d9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -24,6 +24,8 @@ namespace VisualPinball.Unity internal struct PlaneCollider : ICollider { public int Id => _header.Id; + public PhysicsMaterialData Material => _header.Material; + private ColliderHeader _header; From 3fb3e4a7e164c95289000c4fbc703059bad43a20 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 24 Feb 2023 23:21:59 +0100 Subject: [PATCH 038/159] jobs: Add ball movement physics. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 13 ++ .../VPT/Ball/BallMovementPhysics.cs | 119 ++++++++++++++++++ .../VPT/Ball/BallMovementPhysics.cs.meta | 3 + 3 files changed, 135 insertions(+) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index ee3dfd4c0..4aee1e48c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System; +using System.Collections.Generic; using System.Diagnostics; using NativeTrees; using Unity.Burst; @@ -23,6 +24,7 @@ using UnityEngine; using VisualPinball.Engine.Common; using VisualPinball.Unity.VisualPinball.Unity.Game; +using VisualPinballUnity; using Debug = UnityEngine.Debug; namespace VisualPinball.Unity @@ -33,6 +35,8 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeOctree _octree; [NonSerialized] private NativeList _balls; + [NonSerialized] private Dictionary _ballLookup = new(); + private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); private void Start() @@ -70,6 +74,7 @@ private void Start() _balls = new NativeList(balls.Length, Allocator.Persistent); foreach (var ball in balls) { _balls.Add(ball.Data); + _ballLookup[ball.Id] = ball; } } @@ -83,6 +88,14 @@ private void Update() }; updatePhysics.Run(); + + _balls = updatePhysics.Balls; + _physicsState = updatePhysics.PhysicsState; + + foreach (var ballData in _balls) { + var ball = _ballLookup[ballData.Id]; + BallMovementPhysics.Move(ballData, _ballLookup[ball.Id].transform); + } } private void OnDestroy() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs new file mode 100644 index 000000000..03370f86a --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs @@ -0,0 +1,119 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Entities; +using Unity.Mathematics; +using Unity.Profiling; +using UnityEngine; +using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; +using Physics = UnityEngine.Physics; + +namespace VisualPinballUnity +{ + internal static class BallMovementPhysics + { + + private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallMovementSystem"); + + // protected override void OnStartRunning() + // { + // var root = Object.FindObjectOfType(); + // var ltw = root.gameObject.transform.localToWorldMatrix; + // _baseTransform = new float4x4( + // ltw.m00, ltw.m01, ltw.m02, ltw.m03, + // ltw.m10, ltw.m11, ltw.m12, ltw.m13, + // ltw.m20, ltw.m21, ltw.m22, ltw.m23, + // ltw.m30, ltw.m31, ltw.m32, ltw.m33 + // ); + // _player = Object.FindObjectOfType(); + // } + + public static void Move(BallData ball, Transform ballTransform) + { + PerfMarker.Begin(); + + // calculate/adapt height of ball + var zHeight = !ball.IsFrozen ? ball.Position.z : ball.Position.z - ball.Radius; + ballTransform.localPosition = VisualPinball.Unity.Physics.TranslateToWorld(ball.Position.x, ball.Position.y, zHeight); + + var or = ball.BallOrientationForUnity; + + var VPX = new Vector3(or.c0.x, or.c1.x, or.c2.x); + var VPY = new Vector3(or.c0.y, or.c1.y, or.c2.y); + var VPZ = new Vector3(or.c0.z, or.c1.z, or.c2.z); + + // Debug.Log("c0: (" + or.c0.x + ", " + or.c0.y + ", " + or.c0.z + ")"); + // Debug.Log("c1: (" + or.c1.x + ", " + or.c1.y + ", " + or.c1.z + ")"); + // Debug.Log("c2: (" + or.c2.x + ", " + or.c2.y + ", " + or.c2.z + ")"); + + // for security reasons, so that we don't get NaN, NaN, NaN, NaN erroro, when vectors are not fully orthonormalized because of skewMatrix operation + Vector3.OrthoNormalize(ref VPZ, ref VPY, ref VPX); + + Quaternion q = Quaternion.LookRotation(VPZ, VPY); + + // flip Z axis + q = FlipZAxis(q); + + ballTransform.localRotation = q.RotateToWorld(); + + PerfMarker.End(); + + + static Quaternion FlipZAxis(Quaternion q) + { + // which actually flips x and y axis visually... + return new Quaternion(q.x, q.y, -q.z, -q.w); + } + + /* + * I let these two in here, just in case we need them. + + static float3x3 transpose(float3x3 or) + { + float3x3 or2; + or2.c0.x = or.c0.x; + or2.c0.y = or.c1.x; + or2.c0.z = or.c2.x; + or2.c1.x = or.c0.y; + or2.c1.y = or.c1.y; + or2.c1.z = or.c2.y; + or2.c2.x = or.c0.z; + or2.c2.y = or.c1.z; + or2.c2.z = or.c2.z; + return or2; + } + + static Quaternion QuaternionFromMatrix(Matrix4x4 m) + { + // Adapted from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm + Quaternion q = new Quaternion(); + q.w = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] + m[1, 1] + m[2, 2])) / 2; + q.x = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] - m[1, 1] - m[2, 2])) / 2; + q.y = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] + m[1, 1] - m[2, 2])) / 2; + q.z = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] - m[1, 1] + m[2, 2])) / 2; + q.x *= Mathf.Sign(q.x * (m[2, 1] - m[1, 2])); + q.y *= Mathf.Sign(q.y * (m[0, 2] - m[2, 0])); + q.z *= Mathf.Sign(q.z * (m[1, 0] - m[0, 1])); + return q; + } + + */ + + + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs.meta new file mode 100644 index 000000000..1e8a0dbec --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 141124d679c14e43b023645145178e34 +timeCreated: 1679240848 \ No newline at end of file From d4c10f79f3e4b399a56e9b44451a6f39d758faf0 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 25 Feb 2023 23:42:53 +0100 Subject: [PATCH 039/159] jobs: Update ball velocities. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 2 +- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 8 ++++ .../Game/PhysicsStaticNarrowPhase.cs | 8 ++-- .../VPT/Ball/BallVelocityPhysics.cs | 48 +++++++++++++++++++ .../VPT/Ball/BallVelocityPhysics.cs.meta | 3 ++ 5 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index a9e56778f..031277baa 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -75,7 +75,7 @@ internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree contacts) { + private static float HitTest(ref BallData ball, in PlaneCollider coll, ref NativeList contacts) { var newCollEvent = new CollisionEventData(); var newTime = Collider.HitTest(ref ball, in coll, ball.CollisionEvent.HitTime); SaveCollisions(ref ball, ref newCollEvent, ref contacts, in coll, newTime); + + return newTime; } private static void SaveCollisions(ref BallData ball, ref CollisionEventData newCollEvent, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs new file mode 100644 index 000000000..a26a8cc97 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs @@ -0,0 +1,48 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable CompareOfFloatsByEqualityOperator + +using Unity.Mathematics; +using Unity.Profiling; +using VisualPinball.Engine.Common; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class BallVelocityPhysics + { + private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallVelocityPhysics"); + + public static void UpdateVelocities(float3 gravity, ref BallData ball) + { + PerfMarker.Begin(); + + if (ball.ManualControl) { + ball.Velocity *= 0.5f; // Null out most of the X/Y velocity, want a little bit so the ball can sort of find its way out of obstacles. + ball.Velocity += new float3( + math.max(-10.0f, math.min(10.0f, (ball.ManualPosition.x - ball.Position.x) * (float)(1.0/10.0))), + math.max(-10.0f, math.min(10.0f, (ball.ManualPosition.y - ball.Position.y) * (float)(1.0/10.0))), + -2.0f + ); + } else { + ball.Velocity += gravity * (float)PhysicsConstants.PhysFactor; + } + + PerfMarker.End(); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs.meta new file mode 100644 index 000000000..a5c236f6f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d897220282d842e987275304b9cacad9 +timeCreated: 1679264641 \ No newline at end of file From 6f3e9585e34afd038029174da1a55a9aea7ed748 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 11 Mar 2023 23:55:16 +0100 Subject: [PATCH 040/159] fix: Init hit time to -1. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 1 - .../VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs | 6 +++--- .../VisualPinball.Unity/Physics/Collider/Collider.cs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 031277baa..b48bc0abf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -69,7 +69,6 @@ internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree contacts) { - - var newCollEvent = new CollisionEventData(); + private static float HitTest(ref BallData ball, in PlaneCollider coll, ref NativeList contacts) + { + var newCollEvent = new CollisionEventData { HitTime = -1 }; var newTime = Collider.HitTest(ref ball, in coll, ball.CollisionEvent.HitTime); SaveCollisions(ref ball, ref newCollEvent, ref contacts, in coll, newTime); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 2f8330c2d..76dbccd71 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -126,7 +126,7 @@ internal static unsafe float HitTest(ref Collider coll, ref CollisionEventData c internal static float HitTest(ref BallData ball, in PlaneCollider coll, float dTime) { - var collEvent = new CollisionEventData(); + var collEvent = new CollisionEventData { HitTime = -1 }; var hitTime = coll.HitTest(ref collEvent, in ball, dTime); ball.CollisionEvent = collEvent; From 14a903d7257006ae066c39253b4900d8da942c80 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 12 Mar 2023 00:00:07 +0100 Subject: [PATCH 041/159] fix: Don't use extension methods on structs. --- VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs | 2 +- .../VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index b48bc0abf..4fb9ed519 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -74,7 +74,7 @@ internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree Date: Sat, 18 Mar 2023 00:31:25 +0100 Subject: [PATCH 042/159] jobs: Fix collision event. --- .../VisualPinball.Unity/Game/PhysicsBall.cs | 1 - .../VisualPinball.Unity/Game/PhysicsStaticCollision.cs | 5 +++-- .../Game/PhysicsStaticNarrowPhase.cs | 10 +++++----- .../VisualPinball.Unity/Physics/Collider/Collider.cs | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs index 1ff763433..fcdcc9763 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs @@ -17,7 +17,6 @@ // ReSharper disable InconsistentNaming using System; -using Unity.Collections; using Unity.Mathematics; using UnityEngine; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 9272ac169..ccc0b9a0c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -36,12 +36,13 @@ internal static void Collide(float hitTime, ref BallData ball, ref Random random PerfMarker.Begin(); - ball.CollisionEvent.Collider.Collide(ref ball, in ball.CollisionEvent, ref random); + var collEvent = ball.CollisionEvent; + ball.CollisionEvent.Collider.Collide(ref ball, in collEvent, ref random); + ball.CollisionEvent = collEvent; // remove trial hit object pointer ball.CollisionEvent.ClearCollider(); - PerfMarker.End(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index 37619737e..cefb6464b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -47,12 +47,12 @@ internal static void FindNextCollision(float hitTime, ref BallData ball, in Nati private static float HitTest(ref BallData ball, in PlaneCollider coll, ref NativeList contacts) { - var newCollEvent = new CollisionEventData { HitTime = -1 }; - var newTime = Collider.HitTest(ref ball, in coll, ball.CollisionEvent.HitTime); + // var newCollEvent = new CollisionEventData { HitTime = -1 }; + return Collider.HitTest(ref ball, in coll, ball.CollisionEvent.HitTime); - SaveCollisions(ref ball, ref newCollEvent, ref contacts, in coll, newTime); - - return newTime; + // SaveCollisions(ref ball, ref newCollEvent, ref contacts, in coll, newTime); + // + // return newTime; } private static void SaveCollisions(ref BallData ball, ref CollisionEventData newCollEvent, diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 76dbccd71..5933939c0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -126,7 +126,7 @@ internal static unsafe float HitTest(ref Collider coll, ref CollisionEventData c internal static float HitTest(ref BallData ball, in PlaneCollider coll, float dTime) { - var collEvent = new CollisionEventData { HitTime = -1 }; + ref var collEvent = ref ball.CollisionEvent; var hitTime = coll.HitTest(ref collEvent, in ball, dTime); ball.CollisionEvent = collEvent; From 64f86c2e8f1257a3203839edbb66523133334b33 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 21 Mar 2023 22:20:52 +0100 Subject: [PATCH 043/159] jobs: Replace PlaneCollider with Collider. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 9 ++-- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 40 ++++++++++---- .../Game/PhysicsStaticBroadPhase.cs | 2 +- .../Game/PhysicsStaticCollision.cs | 6 ++- .../Game/PhysicsStaticNarrowPhase.cs | 24 ++++----- .../VisualPinball.Unity/Game/Player.cs | 2 +- .../Physics/Collider/Collider.cs | 52 +++++++++++++++++-- .../Collision/ColliderAllocationJob.cs | 38 +++++++++----- .../Physics/Collision/CollisionEventData.cs | 4 +- .../Physics/Collision/QuadTreeCreator.cs | 2 +- .../Collision/StaticCollisionSystem.cs | 2 +- .../VPT/ICollidableComponent.cs | 4 +- .../Playfield/PlayfieldColliderComponent.cs | 6 ++- 13 files changed, 136 insertions(+), 55 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 4fb9ed519..0d4ff92c3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -25,15 +25,16 @@ namespace VisualPinball.Unity public struct PhysicsCycle : IDisposable { private NativeList _contacts; - private NativeList _overlappingColliders; + private NativeList _overlappingColliders; public PhysicsCycle(Allocator a) { _contacts = new NativeList(a); - _overlappingColliders = new NativeList(a); + _overlappingColliders = new NativeList(a); } - internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree octree, ref NativeList balls) + internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree octree, + ref NativeList balls, ref NativeQueue.ParallelWriter events) { var staticCounts = PhysicsConstants.StaticCnts; @@ -84,7 +85,7 @@ internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree _physicsState; - [NonSerialized] private NativeOctree _octree; + [NonSerialized] private NativeOctree _octree; [NonSerialized] private NativeList _balls; + [NonSerialized] private NativeQueue _eventQueue; - [NonSerialized] private Dictionary _ballLookup = new(); + [NonSerialized] private readonly Dictionary _ballLookup = new(); private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); @@ -50,14 +51,26 @@ private void Start() var colliderItems = GetComponentsInChildren(); Debug.Log($"Found {colliderItems.Length} collider items."); - var colliders = new NativeList(Allocator.TempJob); + var managedColliders = new List(); foreach (var colliderItem in colliderItems) { - colliderItem.GetColliders(ref colliders); + colliderItem.GetColliders(managedColliders); + } + + // allocate colliders + var allocateColliderJob = new ColliderAllocationJob(managedColliders); + allocateColliderJob.Run(); + var colliderBlobAssetRef = allocateColliderJob.BlobAsset[0]; + allocateColliderJob.Dispose(); + + // move allocated colliders back into native list + var colliders = new NativeList(Allocator.TempJob); + for (var i = 0; i < colliderBlobAssetRef.Value.Colliders.Length; i++) { + colliders.Add(colliderBlobAssetRef.Value.Colliders[i].Value); } var elapsedMs = sw.Elapsed.TotalMilliseconds; var playfieldBounds = GetComponentInChildren().Bounds; - _octree = new NativeOctree(playfieldBounds, 32, 10, Allocator.Persistent); + _octree = new NativeOctree(playfieldBounds, 32, 10, Allocator.Persistent); sw.Restart(); var populateJob = new PopulatePhysicsJob { @@ -76,15 +89,19 @@ private void Start() _balls.Add(ball.Data); _ballLookup[ball.Id] = ball; } + + _eventQueue = new NativeQueue(Allocator.Persistent); } private void Update() { + var events = _eventQueue.AsParallelWriter(); var updatePhysics = new UpdatePhysicsJob { InitialTimeUsec = NowUsec, PhysicsState = _physicsState, Octree = _octree, Balls = _balls, + Events = events, }; updatePhysics.Run(); @@ -101,6 +118,7 @@ private void Update() private void OnDestroy() { _physicsState.Dispose(); + _eventQueue.Dispose(); _balls.Dispose(); } } @@ -109,13 +127,13 @@ private void OnDestroy() internal struct PopulatePhysicsJob : IJob { [ReadOnly] - public NativeList Colliders; - public NativeOctree Octree; + public NativeList Colliders; + public NativeOctree Octree; public void Execute() { foreach (var collider in Colliders) { - Octree.Insert(collider, collider.Bounds); + Octree.Insert(collider, collider.Bounds().Aabb); } } } @@ -128,10 +146,12 @@ internal struct UpdatePhysicsJob : IJob public NativeArray PhysicsState; - public NativeOctree Octree; + public NativeOctree Octree; public NativeList Balls; + public NativeQueue.ParallelWriter Events; + public void Execute() { var n = 0; @@ -151,7 +171,7 @@ public void Execute() } // simulate cycle - cycle.Simulate(physicsDiffTime, ref state, ref Octree, ref Balls); + cycle.Simulate(physicsDiffTime, ref state, ref Octree, ref Balls, ref Events); state.CurPhysicsFrameTime = state.NextPhysicsFrameTime; state.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs index 3f23e9748..47378ed3b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs @@ -24,7 +24,7 @@ public static class PhysicsStaticBroadPhase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("StaticBroadPhase"); - internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeList overlappingColliders) + internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeList overlappingColliders) { PerfMarker.Begin(); overlappingColliders.Clear(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index ccc0b9a0c..c1d3063fb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -16,6 +16,7 @@ // ReSharper disable ConvertIfStatementToSwitchStatement +using Unity.Collections; using Unity.Mathematics; using Unity.Profiling; using VisualPinball.Unity; @@ -26,7 +27,7 @@ internal static class PhysicsStaticCollision { private static readonly ProfilerMarker PerfMarker = new("PhysicsStaticCollision"); - internal static void Collide(float hitTime, ref BallData ball, ref Random random) + internal static void Collide(float hitTime, ref BallData ball, ref Random random, ref NativeQueue.ParallelWriter events) { // find balls with hit objects and minimum time @@ -37,7 +38,8 @@ internal static void Collide(float hitTime, ref BallData ball, ref Random random PerfMarker.Begin(); var collEvent = ball.CollisionEvent; - ball.CollisionEvent.Collider.Collide(ref ball, in collEvent, ref random); + ref var collider = ref ball.CollisionEvent.Collider; + Collider.Collide(in collider, ref ball, ref events, ball.Id, in ball.CollisionEvent, ref random); ball.CollisionEvent = collEvent; // remove trial hit object pointer diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index cefb6464b..e94495f9a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -21,9 +21,9 @@ namespace VisualPinball.Unity { public static class PhysicsStaticNarrowPhase { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("StaticNarrowPhase"); + private static readonly ProfilerMarker PerfMarker = new("PhysicsStaticNarrowPhase"); - internal static void FindNextCollision(float hitTime, ref BallData ball, in NativeList overlappingColliders, + internal static void FindNextCollision(float hitTime, ref BallData ball, in NativeList overlappingColliders, ref NativeList contacts) { PerfMarker.Begin(); @@ -31,10 +31,10 @@ internal static void FindNextCollision(float hitTime, ref BallData ball, in Nati // init contacts and event ball.CollisionEvent.ClearCollider(hitTime); // search upto current hit time - foreach (var coll in overlappingColliders) { + foreach (var collider in overlappingColliders) { var newCollEvent = new CollisionEventData(); - var newTime = HitTest(ref ball, in coll, ref contacts); - SaveCollisions(ref ball, ref newCollEvent, ref contacts, in coll, newTime); + var newTime = HitTest(ref ball, in collider, ref contacts); + SaveCollisions(ref ball, ref newCollEvent, ref contacts, in collider, newTime); } // no negative time allowed @@ -45,18 +45,16 @@ internal static void FindNextCollision(float hitTime, ref BallData ball, in Nati PerfMarker.End(); } - private static float HitTest(ref BallData ball, in PlaneCollider coll, ref NativeList contacts) + private static float HitTest(ref BallData ball, in Collider collider, ref NativeList contacts) { - // var newCollEvent = new CollisionEventData { HitTime = -1 }; - return Collider.HitTest(ref ball, in coll, ball.CollisionEvent.HitTime); - - // SaveCollisions(ref ball, ref newCollEvent, ref contacts, in coll, newTime); - // - // return newTime; + ref var collEvent = ref ball.CollisionEvent; + var hitTime = Collider.HitTest(in collider, ref collEvent, in ball, ball.CollisionEvent.HitTime); + ball.CollisionEvent = collEvent; + return hitTime; } private static void SaveCollisions(ref BallData ball, ref CollisionEventData newCollEvent, - ref NativeList contacts, in PlaneCollider coll, float newTime) + ref NativeList contacts, in Collider coll, float newTime) { var validHit = newTime >= 0f && !Math.Sign(newTime) && newTime <= ball.CollisionEvent.HitTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index e886b38cc..69dca1323 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -46,7 +46,7 @@ public class Player : MonoBehaviour [NonSerialized] public BallManager BallManager; - public event EventHandler OnPlayerStarted; + public event EventHandler OnPlayeStarted; public List SwitchMapping => _tableComponent.MappingConfig.Switches; public List CoilMapping => _tableComponent.MappingConfig.Coils; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 5933939c0..d42c47b72 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -67,6 +67,8 @@ public unsafe ColliderBounds Bounds() { return ((LineZCollider*) collider)->Bounds; case ColliderType.Point: return ((PointCollider*) collider)->Bounds; + case ColliderType.Plane: + return ((PlaneCollider*) collider)->Bounds; case ColliderType.Plunger: return ((PlungerCollider*) collider)->Bounds; case ColliderType.Spinner: @@ -74,7 +76,7 @@ public unsafe ColliderBounds Bounds() { case ColliderType.Triangle: return ((TriangleCollider*) collider)->Bounds; default: - throw new InvalidOperationException("Cannot compute AABBs for collider " + Type); + throw new InvalidOperationException(); } } } @@ -124,12 +126,56 @@ internal static unsafe float HitTest(ref Collider coll, ref CollisionEventData c } } + internal static unsafe float HitTest(in Collider coll, ref CollisionEventData collEvent, in BallData ball, float dTime) + { + fixed (Collider* collider = &coll) + { + switch (collider->Type) + { + case ColliderType.Bumper: + // case ColliderType.Circle: + // return ((CircleCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); + // case ColliderType.Gate: + // return ((GateCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); + // case ColliderType.Line: + // return ((LineCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); + case ColliderType.LineZ: + return ((LineZCollider*) collider)->HitTest(ref collEvent, in ball, dTime); + case ColliderType.Line3D: + return ((Line3DCollider*) collider)->HitTest(ref collEvent, in ball, dTime); + case ColliderType.Point: + return ((PointCollider*) collider)->HitTest(ref collEvent, in ball, dTime); + case ColliderType.Plane: + return ((PlaneCollider*) collider)->HitTest(ref collEvent, in ball, dTime); + // case ColliderType.Spinner: + // return ((SpinnerCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); + // case ColliderType.Triangle: + // return ((TriangleCollider*) collider)->HitTest(ref collEvent, in insideOf, in ball, dTime); + // case ColliderType.KickerCircle: + // case ColliderType.TriggerCircle: + // return ((CircleCollider*) collider)->HitTestBasicRadius(ref collEvent, ref insideOf, in ball, dTime, false, false, false); + // case ColliderType.TriggerLine: + // return ((LineCollider*) collider)->HitTestBasic(ref collEvent, ref insideOf, in ball, dTime, false, false, false); + + case ColliderType.Plunger: + throw new InvalidOperationException("ColliderType.Plunger must be hit-tested separately!"); + case ColliderType.Flipper: + throw new InvalidOperationException("ColliderType.Flipper must be hit-tested separately!"); + case ColliderType.LineSlingShot: + throw new InvalidOperationException("ColliderType.LineSlingShot must be hit-tested separately!"); + + default: + return -1; + } + } + } + internal static float HitTest(ref BallData ball, in PlaneCollider coll, float dTime) { ref var collEvent = ref ball.CollisionEvent; var hitTime = coll.HitTest(ref collEvent, in ball, dTime); ball.CollisionEvent = collEvent; - + return hitTime; } @@ -137,7 +183,7 @@ internal static float HitTest(ref BallData ball, in PlaneCollider coll, float dT /// Most colliders use the standard Collide3DWall routine, only overrides /// are cast and dispatched to their respective implementation. /// - internal static unsafe void Collide(ref Collider coll, ref BallData ballData, + internal static unsafe void Collide(in Collider coll, ref BallData ballData, ref NativeQueue.ParallelWriter events, in int ballId, in CollisionEventData collEvent, ref Random random) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs index 6c5429515..05b5c21ba 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs @@ -24,6 +24,19 @@ namespace VisualPinball.Unity { + /// + /// This job converts a list of managed ICollider objects into unmanaged Collider structs.
+ /// + /// However, the output is not a list, but a NativeArray of length of 1, containing a BlobAssetReference + /// of ColliderBlob, which contains a BlobArray of BlobPtr of Collider. + ///
+ /// + /// + /// for (var i = 0; i < BlobAsset[0].Value.Colliders.Length; i++) { + /// var collider = BlobAsset[0].Value.Colliders[i].Value; + /// } + /// + /// [BurstCompile] internal struct ColliderAllocationJob : IJob, IDisposable { @@ -38,11 +51,15 @@ internal struct ColliderAllocationJob : IJob, IDisposable [ReadOnly] private NativeList _pointColliders; [ReadOnly] private NativeList _spinnerColliders; [ReadOnly] private NativeList _triangleColliders; - [ReadOnly] private NativeArray _planeColliders; + [ReadOnly] private NativeList _planeColliders; + /// + /// The result: A blob asset of allocated Collider structs that can be casted to + /// their respective type. + /// public NativeArray> BlobAsset; - public ColliderAllocationJob(IEnumerable colliderList, PlaneCollider playfieldCollider, PlaneCollider glassCollider) : this() + public ColliderAllocationJob(IEnumerable colliderList) : this() { var perfMarker = new ProfilerMarker("ColliderAllocationJob.ctr"); perfMarker.Begin(); @@ -58,10 +75,7 @@ public ColliderAllocationJob(IEnumerable colliderList, PlaneCollider _pointColliders = new NativeList(Allocator.TempJob); _spinnerColliders = new NativeList(Allocator.TempJob); _triangleColliders = new NativeList(Allocator.TempJob); - _planeColliders = new NativeArray(2, Allocator.TempJob) { - [0] = playfieldCollider, - [1] = glassCollider - }; + _planeColliders = new NativeList(Allocator.TempJob); BlobAsset = new NativeArray>(1, Allocator.TempJob); @@ -75,6 +89,7 @@ public ColliderAllocationJob(IEnumerable colliderList, PlaneCollider case Line3DCollider line3DCollider: _line3DColliders.Add(line3DCollider); break; case LineSlingshotCollider lineSlingshotCollider: _lineSlingshotColliders.Add(lineSlingshotCollider); break; case LineZCollider lineZCollider: _lineZColliders.Add(lineZCollider); break; + case PlaneCollider planeCollider: _planeColliders.Add(planeCollider); break; case PlungerCollider plungerCollider: _plungerColliders.Add(plungerCollider); break; case PointCollider pointCollider: _pointColliders.Add(pointCollider); break; case SpinnerCollider spinnerCollider: _spinnerColliders.Add(spinnerCollider); break; @@ -95,12 +110,6 @@ public void Execute() var colliders = builder.Allocate(ref root.Colliders, count); - _planeColliders[0].Allocate(builder, ref colliders, colliderId++); - _planeColliders[1].Allocate(builder, ref colliders, colliderId++); - - root.PlayfieldColliderId = _planeColliders[0].Id; - root.GlassColliderId = _planeColliders[1].Id; - // copy generated colliders into blob array for (var i = 0; i < _circleColliders.Length; i++) { _circleColliders[i].Allocate(builder, ref colliders, colliderId++); @@ -123,6 +132,9 @@ public void Execute() for (var i = 0; i < _lineZColliders.Length; i++) { _lineZColliders[i].Allocate(builder, ref colliders, colliderId++); } + for (var i = 0; i < _planeColliders.Length; i++) { + _planeColliders[i].Allocate(builder, ref colliders, colliderId++); + } for (var i = 0; i < _plungerColliders.Length; i++) { _plungerColliders[i].Allocate(builder, ref colliders, colliderId++); } @@ -149,11 +161,11 @@ public void Dispose() _lineSlingshotColliders.Dispose(); _lineColliders.Dispose(); _lineZColliders.Dispose(); + _planeColliders.Dispose(); _plungerColliders.Dispose(); _pointColliders.Dispose(); _spinnerColliders.Dispose(); _triangleColliders.Dispose(); - _planeColliders.Dispose(); BlobAsset.Dispose(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs index 8904ce82c..c5c0de15f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs @@ -29,11 +29,11 @@ internal struct CollisionEventData : IComponentData public float HitOrgNormalVelocity; public bool IsContact; - public PlaneCollider Collider; + public Collider Collider; public int ColliderId; public int BallId; - public void SetCollider(PlaneCollider collider) + public void SetCollider(Collider collider) { Collider = collider; ColliderId = collider.Id; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs index 7e9f174ae..d6104f655 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs @@ -62,7 +62,7 @@ public static void Create(EntityManager entityManager, out NativeHashMap. -using Unity.Collections; +using System.Collections.Generic; namespace VisualPinball.Unity { public interface ICollidableComponent { - internal void GetColliders(ref NativeList colliders); + internal void GetColliders(List colliders); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs index 015342f1e..cf8c16222 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs @@ -17,7 +17,9 @@ // ReSharper disable InconsistentNaming using System; +using System.Collections.Generic; using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Table; @@ -58,12 +60,12 @@ public class PlayfieldColliderComponent : ColliderComponent new PlayfieldApi(gameObject, player); - void ICollidableComponent.GetColliders(ref NativeList colliders) + void ICollidableComponent.GetColliders(List colliders) { var api = new PlayfieldApi(gameObject, GetComponent()); var c = api.CreateColliders(GetInstanceID()); colliders.Add(c.Item1); - colliders.Add(c.Item2); + //colliders.Add(c.Item2); } } } From 021cdd8ef3247792d0edc2810a018537ec162ca8 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 22 Mar 2023 00:53:00 +0100 Subject: [PATCH 044/159] jobs: Reuse colliders in blob and make all methods static. --- .../Game/PhysicsColliderExtensions.cs | 45 +++++++++++++++++++ .../Game/PhysicsColliderExtensions.cs.meta | 3 ++ .../VisualPinball.Unity/Game/PhysicsCycle.cs | 17 +++---- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 42 ++++++++--------- .../Game/PhysicsStaticBroadPhase.cs | 2 +- .../Game/PhysicsStaticCollision.cs | 15 +++++-- .../Game/PhysicsStaticNarrowPhase.cs | 28 +++++++++--- .../Physics/Collider/Collider.cs | 9 ---- .../Physics/Collider/PlaneCollider.cs | 32 +++++++------ .../Collision/ColliderAllocationJob.cs | 3 +- .../Physics/Collision/CollisionEventData.cs | 12 +---- 11 files changed, 130 insertions(+), 78 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs new file mode 100644 index 000000000..cfa2e9aaf --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs @@ -0,0 +1,45 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Collections.LowLevel.Unsafe; +using Unity.Entities; + +namespace VisualPinball.Unity +{ + public static class PhysicsColliderExtensions + { + internal static int GetId(this BlobAssetReference colliders, int index) + => colliders.Value.Colliders[index].Value.Id; + + internal static ColliderType GetType(this BlobAssetReference colliders, int index) + => colliders.Value.Colliders[index].Value.Type; + + internal static float GetFriction(this BlobAssetReference colliders, int index) + => colliders.Value.Colliders[index].Value.Material.Friction; + + internal static Aabb GetAabb(this BlobAssetReference colliders, int index) + => colliders.Value.Colliders[index].Value.Bounds().Aabb; + + internal static unsafe ref PlaneCollider GetPlaneCollider(this ref BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var planeCollider = (PlaneCollider*) cPtr; + return ref UnsafeUtility.AsRef(planeCollider); + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs.meta new file mode 100644 index 000000000..56a88bd5c --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d5d02c30bc514422ad04ca0f05eda526 +timeCreated: 1681165885 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 0d4ff92c3..e8e778305 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -17,6 +17,7 @@ using System; using NativeTrees; using Unity.Collections; +using Unity.Entities; using VisualPinball.Engine.Common; using VisualPinballUnity; @@ -25,18 +26,18 @@ namespace VisualPinball.Unity public struct PhysicsCycle : IDisposable { private NativeList _contacts; - private NativeList _overlappingColliders; + private NativeList _overlappingColliders; public PhysicsCycle(Allocator a) { _contacts = new NativeList(a); - _overlappingColliders = new NativeList(a); + _overlappingColliders = new NativeList(a); } - internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree octree, - ref NativeList balls, ref NativeQueue.ParallelWriter events) + internal void Simulate(float dTime, ref PhysicsState state, in NativeOctree octree, + ref BlobAssetReference colliders, ref NativeList balls, ref NativeQueue.ParallelWriter events) { - + var staticCounts = PhysicsConstants.StaticCnts; while (dTime > 0) { @@ -61,7 +62,7 @@ internal void Simulate(float dTime, ref PhysicsState state, ref NativeOctree _physicsState; - [NonSerialized] private NativeOctree _octree; + [NonSerialized] private NativeOctree _octree; [NonSerialized] private NativeList _balls; [NonSerialized] private NativeQueue _eventQueue; + [NonSerialized] private BlobAssetReference _colliders; [NonSerialized] private readonly Dictionary _ballLookup = new(); @@ -59,28 +61,22 @@ private void Start() // allocate colliders var allocateColliderJob = new ColliderAllocationJob(managedColliders); allocateColliderJob.Run(); - var colliderBlobAssetRef = allocateColliderJob.BlobAsset[0]; + _colliders = allocateColliderJob.BlobAsset[0]; allocateColliderJob.Dispose(); - // move allocated colliders back into native list - var colliders = new NativeList(Allocator.TempJob); - for (var i = 0; i < colliderBlobAssetRef.Value.Colliders.Length; i++) { - colliders.Add(colliderBlobAssetRef.Value.Colliders[i].Value); - } - + // create octree var elapsedMs = sw.Elapsed.TotalMilliseconds; var playfieldBounds = GetComponentInChildren().Bounds; - _octree = new NativeOctree(playfieldBounds, 32, 10, Allocator.Persistent); + _octree = new NativeOctree(playfieldBounds, 32, 10, Allocator.Persistent); sw.Restart(); var populateJob = new PopulatePhysicsJob { - Colliders = colliders, + Colliders = _colliders, Octree = _octree, }; populateJob.Run(); _octree = populateJob.Octree; - Debug.Log($"Octree of {colliders.Length} constructed (colliders: {elapsedMs}ms, tree: {sw.Elapsed.TotalMilliseconds}ms)."); - colliders.Dispose(); + Debug.Log($"Octree of {_colliders.Value.Colliders.Length} constructed (colliders: {elapsedMs}ms, tree: {sw.Elapsed.TotalMilliseconds}ms)."); // get balls var balls = GetComponentsInChildren(); @@ -100,6 +96,7 @@ private void Update() InitialTimeUsec = NowUsec, PhysicsState = _physicsState, Octree = _octree, + Colliders = _colliders, Balls = _balls, Events = events, }; @@ -120,6 +117,7 @@ private void OnDestroy() _physicsState.Dispose(); _eventQueue.Dispose(); _balls.Dispose(); + _colliders.Dispose(); } } @@ -127,13 +125,13 @@ private void OnDestroy() internal struct PopulatePhysicsJob : IJob { [ReadOnly] - public NativeList Colliders; - public NativeOctree Octree; + public BlobAssetReference Colliders; + public NativeOctree Octree; public void Execute() { - foreach (var collider in Colliders) { - Octree.Insert(collider, collider.Bounds().Aabb); + for (var i = 0; i < Colliders.Value.Colliders.Length; i++) { + Octree.Insert(Colliders.GetId(i), Colliders.GetAabb(i)); } } } @@ -143,13 +141,10 @@ internal struct UpdatePhysicsJob : IJob { [ReadOnly] public ulong InitialTimeUsec; - public NativeArray PhysicsState; - - public NativeOctree Octree; - + public NativeOctree Octree; + public BlobAssetReference Colliders; public NativeList Balls; - public NativeQueue.ParallelWriter Events; public void Execute() @@ -158,6 +153,7 @@ public void Execute() var state = PhysicsState[0]; var cycle = new PhysicsCycle(Allocator.Temp); + while (state.CurPhysicsFrameTime < InitialTimeUsec) { var timeMsec = (uint)((state.CurPhysicsFrameTime - state.StartTimeUsec) / 1000); @@ -171,7 +167,7 @@ public void Execute() } // simulate cycle - cycle.Simulate(physicsDiffTime, ref state, ref Octree, ref Balls, ref Events); + cycle.Simulate(physicsDiffTime, ref state, in Octree, ref Colliders, ref Balls, ref Events); state.CurPhysicsFrameTime = state.NextPhysicsFrameTime; state.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; @@ -181,8 +177,6 @@ public void Execute() PhysicsState[0] = state; cycle.Dispose(); - - //Debug.Log($"UpdatePhysic {n}x"); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs index 47378ed3b..191837fcd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs @@ -24,7 +24,7 @@ public static class PhysicsStaticBroadPhase { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("StaticBroadPhase"); - internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeList overlappingColliders) + internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeList overlappingColliders) { PerfMarker.Begin(); overlappingColliders.Clear(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index c1d3063fb..2ab6f1fd3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -17,6 +17,7 @@ // ReSharper disable ConvertIfStatementToSwitchStatement using Unity.Collections; +using Unity.Entities; using Unity.Mathematics; using Unity.Profiling; using VisualPinball.Unity; @@ -27,7 +28,7 @@ internal static class PhysicsStaticCollision { private static readonly ProfilerMarker PerfMarker = new("PhysicsStaticCollision"); - internal static void Collide(float hitTime, ref BallData ball, ref Random random, ref NativeQueue.ParallelWriter events) + internal static void Collide(float hitTime, ref BallData ball, ref BlobAssetReference colliders, ref Random random, ref NativeQueue.ParallelWriter events) { // find balls with hit objects and minimum time @@ -38,8 +39,7 @@ internal static void Collide(float hitTime, ref BallData ball, ref Random random PerfMarker.Begin(); var collEvent = ball.CollisionEvent; - ref var collider = ref ball.CollisionEvent.Collider; - Collider.Collide(in collider, ref ball, ref events, ball.Id, in ball.CollisionEvent, ref random); + Collide(ref ball, ref colliders, ref random, ref events); ball.CollisionEvent = collEvent; // remove trial hit object pointer @@ -47,5 +47,14 @@ internal static void Collide(float hitTime, ref BallData ball, ref Random random PerfMarker.End(); } + + private static void Collide(ref BallData ball, ref BlobAssetReference colliders, ref Random random, ref NativeQueue.ParallelWriter events) + { + switch (colliders.GetType(ball.CollisionEvent.ColliderId)) { + case ColliderType.Plane: + PlaneCollider.Collide(colliders.GetPlaneCollider(ball.CollisionEvent.ColliderId), ref ball, in ball.CollisionEvent, ref random); + break; + } + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index e94495f9a..8bb5b79ac 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using Unity.Collections; +using Unity.Entities; using Unity.Profiling; namespace VisualPinball.Unity @@ -23,18 +24,18 @@ public static class PhysicsStaticNarrowPhase { private static readonly ProfilerMarker PerfMarker = new("PhysicsStaticNarrowPhase"); - internal static void FindNextCollision(float hitTime, ref BallData ball, in NativeList overlappingColliders, - ref NativeList contacts) + internal static void FindNextCollision(float hitTime, ref BallData ball, in NativeList overlappingColliders, + ref BlobAssetReference colliders, ref NativeList contacts) { PerfMarker.Begin(); // init contacts and event ball.CollisionEvent.ClearCollider(hitTime); // search upto current hit time - foreach (var collider in overlappingColliders) { + foreach (var colliderId in overlappingColliders) { var newCollEvent = new CollisionEventData(); - var newTime = HitTest(ref ball, in collider, ref contacts); - SaveCollisions(ref ball, ref newCollEvent, ref contacts, in collider, newTime); + var newTime = HitTest(ref ball, colliderId, ref colliders, ref contacts); + SaveCollisions(ref ball, ref newCollEvent, ref contacts, colliderId, newTime); } // no negative time allowed @@ -45,6 +46,19 @@ internal static void FindNextCollision(float hitTime, ref BallData ball, in Nati PerfMarker.End(); } + private static float HitTest(ref BallData ball, int colliderId, ref BlobAssetReference colliders, ref NativeList contacts) + { + ref var collEvent = ref ball.CollisionEvent; + var hitTime = -1f; + switch (colliders.GetType(colliderId)) { + case ColliderType.Plane: + hitTime = PlaneCollider.HitTest(in colliders.GetPlaneCollider(colliderId), ref collEvent, in ball, ball.CollisionEvent.HitTime); + break; + } + ball.CollisionEvent = collEvent; + return hitTime; + } + private static float HitTest(ref BallData ball, in Collider collider, ref NativeList contacts) { ref var collEvent = ref ball.CollisionEvent; @@ -54,12 +68,12 @@ private static float HitTest(ref BallData ball, in Collider collider, ref Native } private static void SaveCollisions(ref BallData ball, ref CollisionEventData newCollEvent, - ref NativeList contacts, in Collider coll, float newTime) + ref NativeList contacts, int colliderId, float newTime) { var validHit = newTime >= 0f && !Math.Sign(newTime) && newTime <= ball.CollisionEvent.HitTime; if (newCollEvent.IsContact || validHit) { - newCollEvent.SetCollider(coll); + newCollEvent.SetCollider(colliderId, ball.Id); newCollEvent.HitTime = newTime; if (newCollEvent.IsContact) { contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index d42c47b72..817c91384 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -169,15 +169,6 @@ internal static unsafe float HitTest(in Collider coll, ref CollisionEventData co } } } - - internal static float HitTest(ref BallData ball, in PlaneCollider coll, float dTime) - { - ref var collEvent = ref ball.CollisionEvent; - var hitTime = coll.HitTest(ref collEvent, in ball, dTime); - ball.CollisionEvent = collEvent; - - return hitTime; - } /// /// Most colliders use the standard Collide3DWall routine, only overrides diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index 2d91bc3d9..1fe1dce68 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -29,16 +29,16 @@ internal struct PlaneCollider : ICollider private ColliderHeader _header; - private readonly float3 _normal; - private readonly float _distance; + public readonly float3 Normal; + public readonly float Distance; public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb(float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue)); public PlaneCollider(float3 normal, float distance, ColliderInfo info) : this() { _header.Init(info, ColliderType.Plane); - _normal = normal; - _distance = distance; + Normal = normal; + Distance = distance; } public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) @@ -55,15 +55,15 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray PhysicsConstants.ContactVel) { @@ -71,7 +71,7 @@ public float HitTest(ref CollisionEventData collEvent, in BallData ball, float d } // distance from plane to ball surface - var bnd = math.dot(_normal, ball.Position) - ball.Radius - _distance; + var bnd = math.dot(planeColl.Normal, ball.Position) - ball.Radius - planeColl.Distance; //!! solely responsible for ball through playfield?? check other places, too (radius*2??) if (bnd < ball.Radius * -2.0) { @@ -82,7 +82,7 @@ public float HitTest(ref CollisionEventData collEvent, in BallData ball, float d if (math.abs(bnv) <= PhysicsConstants.ContactVel) { if (math.abs(bnd) <= PhysicsConstants.PhysTouch) { collEvent.IsContact = true; - collEvent.HitNormal = _normal; + collEvent.HitNormal = planeColl.Normal; collEvent.HitOrgNormalVelocity = bnv; // remember original normal velocity collEvent.HitDistance = bnd; @@ -106,28 +106,32 @@ public float HitTest(ref CollisionEventData collEvent, in BallData ball, float d return -1.0f; } - collEvent.HitNormal = _normal; + collEvent.HitNormal = planeColl.Normal; collEvent.HitDistance = bnd; // actual contact distance return hitTime; } + public float HitTest(ref CollisionEventData collEvent, in BallData ball, float dTime) => HitTest(this, ref collEvent, ball, dTime); + #endregion #region Collision - public void Collide(ref BallData ball, in CollisionEventData collEvent, ref Random random) + public static void Collide(in PlaneCollider planeColl, ref BallData ball, in CollisionEventData collEvent, ref Random random) { - BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); + BallCollider.Collide3DWall(ref ball, in planeColl._header.Material, in collEvent, in collEvent.HitNormal, ref random); // distance from plane to ball surface - var bnd = math.dot(_normal, ball.Position) - ball.Radius - _distance; + var bnd = math.dot(planeColl.Normal, ball.Position) - ball.Radius - planeColl.Distance; if (bnd < 0) { // if ball has penetrated, push it out of the plane - ball.Position -= _normal * bnd; + ball.Position -= planeColl.Normal * bnd; } } + public void Collide(ref BallData ball, in CollisionEventData collEvent, ref Random random) => Collide(this, ref ball, in collEvent, ref random); + #endregion } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs index 05b5c21ba..fe24c73cd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs @@ -77,7 +77,7 @@ public ColliderAllocationJob(IEnumerable colliderList) : this() _triangleColliders = new NativeList(Allocator.TempJob); _planeColliders = new NativeList(Allocator.TempJob); - BlobAsset = new NativeArray>(1, Allocator.TempJob); + BlobAsset = new NativeArray>(1, Allocator.Persistent); // separate created colliders per type foreach (var collider in colliderList) { @@ -166,7 +166,6 @@ public void Dispose() _pointColliders.Dispose(); _spinnerColliders.Dispose(); _triangleColliders.Dispose(); - BlobAsset.Dispose(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs index c5c0de15f..4d0a4fc53 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs @@ -29,21 +29,13 @@ internal struct CollisionEventData : IComponentData public float HitOrgNormalVelocity; public bool IsContact; - public Collider Collider; public int ColliderId; public int BallId; - - public void SetCollider(Collider collider) - { - Collider = collider; - ColliderId = collider.Id; - BallId = 0; - } - public void SetCollider(int colliderId) + public void SetCollider(int colliderId, int ballId = 0) { ColliderId = colliderId; - BallId = 0; + BallId = ballId; } public void SetBallItem(int ballId) From f83c012bf10b5537d814ef92335783ccbcd6c7d2 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 25 Mar 2023 00:58:56 +0100 Subject: [PATCH 045/159] jobs: Non-static was actually fine. --- .../Game/PhysicsStaticCollision.cs | 2 +- .../Game/PhysicsStaticNarrowPhase.cs | 2 +- .../Physics/Collider/PlaneCollider.cs | 32 ++++++++----------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 2ab6f1fd3..8292729c2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -52,7 +52,7 @@ private static void Collide(ref BallData ball, ref BlobAssetReference new ColliderBounds(_header.ItemId, _header.Id, new Aabb(float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue)); public PlaneCollider(float3 normal, float distance, ColliderInfo info) : this() { _header.Init(info, ColliderType.Plane); - Normal = normal; - Distance = distance; + _normal = normal; + _distance = distance; } public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) @@ -55,15 +55,15 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray PhysicsConstants.ContactVel) { @@ -71,7 +71,7 @@ public static float HitTest(in PlaneCollider planeColl, ref CollisionEventData c } // distance from plane to ball surface - var bnd = math.dot(planeColl.Normal, ball.Position) - ball.Radius - planeColl.Distance; + var bnd = math.dot(_normal, ball.Position) - ball.Radius - _distance; //!! solely responsible for ball through playfield?? check other places, too (radius*2??) if (bnd < ball.Radius * -2.0) { @@ -82,7 +82,7 @@ public static float HitTest(in PlaneCollider planeColl, ref CollisionEventData c if (math.abs(bnv) <= PhysicsConstants.ContactVel) { if (math.abs(bnd) <= PhysicsConstants.PhysTouch) { collEvent.IsContact = true; - collEvent.HitNormal = planeColl.Normal; + collEvent.HitNormal = _normal; collEvent.HitOrgNormalVelocity = bnv; // remember original normal velocity collEvent.HitDistance = bnd; @@ -106,32 +106,28 @@ public static float HitTest(in PlaneCollider planeColl, ref CollisionEventData c return -1.0f; } - collEvent.HitNormal = planeColl.Normal; + collEvent.HitNormal = _normal; collEvent.HitDistance = bnd; // actual contact distance return hitTime; } - public float HitTest(ref CollisionEventData collEvent, in BallData ball, float dTime) => HitTest(this, ref collEvent, ball, dTime); - #endregion #region Collision - public static void Collide(in PlaneCollider planeColl, ref BallData ball, in CollisionEventData collEvent, ref Random random) + public void Collide(ref BallData ball, in CollisionEventData collEvent, ref Random random) { - BallCollider.Collide3DWall(ref ball, in planeColl._header.Material, in collEvent, in collEvent.HitNormal, ref random); + BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); // distance from plane to ball surface - var bnd = math.dot(planeColl.Normal, ball.Position) - ball.Radius - planeColl.Distance; + var bnd = math.dot(_normal, ball.Position) - ball.Radius - _distance; if (bnd < 0) { // if ball has penetrated, push it out of the plane - ball.Position -= planeColl.Normal * bnd; + ball.Position -= _normal * bnd; } } - public void Collide(ref BallData ball, in CollisionEventData collEvent, ref Random random) => Collide(this, ref ball, in collEvent, ref random); - #endregion } } From 34d7e8a486985bceecabd73074d3b5a663e7b31d Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 26 Mar 2023 23:21:20 +0200 Subject: [PATCH 046/159] jobs: Do collider generation through previous interface. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 4 +- .../Physics/Collision/QuadTreeCreator.cs | 2 +- .../VisualPinball.Unity/VPT/CollidableApi.cs | 4 +- .../VPT/ICollidableComponent.cs | 2 +- .../VPT/Playfield/PlayfieldApi.cs | 45 ++++++++++--------- .../Playfield/PlayfieldColliderComponent.cs | 10 +---- 6 files changed, 32 insertions(+), 35 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index f77fc8e1d..fc0f4bc41 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -44,6 +44,8 @@ public class PhysicsEngine : MonoBehaviour private void Start() { + var player = GetComponent(); + // init state _physicsState = new NativeArray(1, Allocator.Persistent); _physicsState[0] = new PhysicsState(NowUsec, GetComponent()); @@ -55,7 +57,7 @@ private void Start() Debug.Log($"Found {colliderItems.Length} collider items."); var managedColliders = new List(); foreach (var colliderItem in colliderItems) { - colliderItem.GetColliders(managedColliders); + colliderItem.GetColliders(player, managedColliders, 0); } // allocate colliders diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs index d6104f655..f1916916d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs @@ -47,7 +47,7 @@ public static void Create(EntityManager entityManager, out NativeHashMap(); - var (playfieldCollider, glassCollider) = player.PlayfieldApi.CreateColliders(0); + //var (playfieldCollider, glassCollider) = player.PlayfieldApi.CreateColliders(0); itemsColliding = new NativeHashMap(itemApis.Length, Allocator.Persistent); foreach (var itemApi in itemApis) { // fixme job diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs index 0d9d7f24e..b088ea9dc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs @@ -81,9 +81,9 @@ void IApiColliderGenerator.CreateColliders(List colliders, float marg public ColliderInfo GetColliderInfo(ItemType itemType) { return new ColliderInfo { - Id = -1, - ItemType = itemType, + Id = -1, // is set during allocation ItemId = ItemId, + ItemType = itemType, FireEvents = FireHitEvents, IsEnabled = ColliderComponent && ColliderComponent.isActiveAndEnabled, Material = ColliderComponent.PhysicsMaterialData, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs index c2c2cd3fe..e7a6ed9b0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs @@ -20,6 +20,6 @@ namespace VisualPinball.Unity { public interface ICollidableComponent { - internal void GetColliders(List colliders); + internal void GetColliders(Player player, List colliders, float margin); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs index ba00d514c..132476627 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs @@ -34,14 +34,37 @@ internal PlayfieldApi(GameObject go, Player player) : base(go, player) protected override void CreateColliders(List colliders, float margin) { var info = ((IApiColliderGenerator)this).GetColliderInfo(); + var planeColliderInfo = new ColliderInfo { + Id = -1, // is set during allocation + ItemId = ItemId, + ItemType = ItemType.Table, + FireEvents = false, + IsEnabled = true, + Material = new PhysicsMaterialData { + Elasticity = ColliderComponent.Elasticity, + ElasticityFalloff = ColliderComponent.ElasticityFalloff, + Friction = ColliderComponent.Friction, + ScatterAngleRad = ColliderComponent.Scatter + }, + HitThreshold = 0 + }; + // do we have a playfield mesh? var meshComp = GameObject.GetComponent(); if (meshComp && !meshComp.AutoGenerate) { var mf = GameObject.GetComponent(); if (mf && mf.sharedMesh) { ColliderUtils.GenerateCollidersFromMesh(mf.sharedMesh.ToVpMesh(), info, colliders); + + } else { + Debug.LogWarning($"Could not find mesh filter on playfield {GameObject.name}"); + colliders.Add(new PlaneCollider(new float3(0, 0, 1), MainComponent.TableHeight, planeColliderInfo)); } + } else { + colliders.Add(new PlaneCollider(new float3(0, 0, 1), MainComponent.TableHeight, planeColliderInfo)); } + // add playfield glass collider + colliders.Add(new PlaneCollider(new float3(0, 0, -1), MainComponent.GlassHeight, planeColliderInfo)); if (ColliderComponent.CollideWithBounds) { @@ -89,28 +112,6 @@ protected override void CreateColliders(List colliders, float margin) ColliderUtils.Generate3DPolyColliders(rgv3D, info, colliders); } - internal (PlaneCollider, PlaneCollider) CreateColliders(int instanceId) - { - var info = new ColliderInfo { - ItemId = instanceId, - ItemType = ItemType.Table, - FireEvents = false, - IsEnabled = true, - Material = new PhysicsMaterialData { - Elasticity = ColliderComponent.Elasticity, - ElasticityFalloff = ColliderComponent.ElasticityFalloff, - Friction = ColliderComponent.Friction, - ScatterAngleRad = ColliderComponent.Scatter - }, - HitThreshold = 0 - }; - - return ( - new PlaneCollider(new float3(0, 0, 1), MainComponent.TableHeight, info), - new PlaneCollider(new float3(0, 0, -1), MainComponent.GlassHeight, info) - ); - } - #endregion } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs index cf8c16222..45c333f1e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs @@ -18,9 +18,6 @@ using System; using System.Collections.Generic; -using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Table; @@ -60,12 +57,9 @@ public class PlayfieldColliderComponent : ColliderComponent new PlayfieldApi(gameObject, player); - void ICollidableComponent.GetColliders(List colliders) + void ICollidableComponent.GetColliders(Player player, List colliders, float margin) { - var api = new PlayfieldApi(gameObject, GetComponent()); - var c = api.CreateColliders(GetInstanceID()); - colliders.Add(c.Item1); - //colliders.Add(c.Item2); + InstantiateColliderApi(player).CreateColliders(colliders, margin); } } } From e72c33a73e05dd8c256a858e63b2846f024a7ee8 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 30 Mar 2023 23:30:59 +0200 Subject: [PATCH 047/159] jobs: Convert playfield mesh to VPX space. --- .../VisualPinball.Unity/Physics/Collider/ColliderUtils.cs | 1 - .../VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs index 80ca435be..1d39d9842 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs @@ -47,7 +47,6 @@ public static void Generate3DPolyColliders(in float3[] rgv, ColliderInfo info, I public static void GenerateCollidersFromMesh(Mesh mesh, ColliderInfo info, ICollection colliders, bool onlyTriangles = false) { var addedEdges = EdgeSet.Get(); - var collCount = colliders.Count; // add collision triangles and edges for (var i = 0; i < mesh.Indices.Length; i += 3) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs index 132476627..dd4cfc70a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs @@ -54,7 +54,7 @@ protected override void CreateColliders(List colliders, float margin) if (meshComp && !meshComp.AutoGenerate) { var mf = GameObject.GetComponent(); if (mf && mf.sharedMesh) { - ColliderUtils.GenerateCollidersFromMesh(mf.sharedMesh.ToVpMesh(), info, colliders); + ColliderUtils.GenerateCollidersFromMesh(mf.sharedMesh.ToVpMesh().TransformToVpx(), info, colliders); } else { Debug.LogWarning($"Could not find mesh filter on playfield {GameObject.name}"); From 25cdde23ae6ba329696568795af13d2b1554adf7 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 29 Sep 2023 10:56:00 +0200 Subject: [PATCH 048/159] jobs: Add line collider. --- .../VPT/ColliderInspector.cs | 4 + .../VisualPinball.Unity/Game/InsideOfs.cs | 90 +++++++++++++++++++ .../Game/InsideOfs.cs.meta | 3 + .../Game/PhysicsColliderExtensions.cs | 11 ++- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 11 ++- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 11 ++- .../Game/PhysicsStaticCollision.cs | 5 +- .../Game/PhysicsStaticNarrowPhase.cs | 24 +++-- .../Physics/Collider/CircleCollider.cs | 11 +-- .../Physics/Collider/Collider.cs | 14 +-- .../Physics/Collider/LineCollider.cs | 28 +++--- .../Physics/Collider/LineSlingshotCollider.cs | 8 +- .../Physics/Collider/PlaneCollider.cs | 22 +++-- .../Physics/Collider/TriangleCollider.cs | 6 +- .../Collision/StaticCollisionSystem.cs | 22 ++--- .../Collision/StaticNarrowPhaseSystem.cs | 18 ++-- .../VisualPinball.Unity/VPT/Ball/BallData.cs | 30 ------- .../VPT/ColliderComponent.cs | 29 +++++- .../VPT/Flipper/FlipperCollider.cs | 2 +- .../VPT/Gate/GateCollider.cs | 6 +- .../VPT/Kicker/KickerCollider.cs | 8 +- .../VPT/Playfield/PlayfieldApi.cs | 16 ++-- .../VPT/Plunger/PlungerCollider.cs | 13 +-- .../VPT/Spinner/SpinnerCollider.cs | 7 +- .../VPT/Trigger/TriggerCollider.cs | 15 ++-- 25 files changed, 277 insertions(+), 137 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/ColliderInspector.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/ColliderInspector.cs index 5ce721c78..fb6248fdc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/ColliderInspector.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/ColliderInspector.cs @@ -80,6 +80,10 @@ public override void OnInspectorGUI() var showColliders = EditorGUILayout.Toggle("Show Colliders", ColliderComponent.ShowColliderMesh); refresh = refresh || showColliders != ColliderComponent.ShowColliderMesh; ColliderComponent.ShowColliderMesh = showColliders; + + var showOctree = EditorGUILayout.Toggle("Show Octree", ColliderComponent.ShowColliderOctree); + refresh = refresh || showOctree != ColliderComponent.ShowColliderOctree; + ColliderComponent.ShowColliderOctree = showOctree; } EditorGUILayout.EndFoldoutHeaderGroup(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs new file mode 100644 index 000000000..550967605 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs @@ -0,0 +1,90 @@ +using System; +using Unity.Collections; + +namespace VisualPinball.Unity +{ + internal struct InsideOfs : IDisposable + { + private NativeParallelHashMap _bitLookup; + private NativeParallelHashMap _insideOfs; + + public InsideOfs(Allocator allocator) + { + _bitLookup = new NativeParallelHashMap(64, allocator); + _insideOfs = new NativeParallelHashMap(64, allocator); + } + + internal void SetInsideOf(int itemId, int ballId) + { + if (!_insideOfs.ContainsKey(itemId)) { + _insideOfs.Add(itemId, new BitField64()); + } + + _insideOfs[itemId].SetBits(GetBitIndex(ballId), true); + } + + internal void SetOutsideOf(int itemId, int ballId) + { + if (!_insideOfs.ContainsKey(itemId)) { + return; + } + + _insideOfs[itemId].SetBits(GetBitIndex(ballId), false); + ClearBitIndex(ballId); + ClearItems(itemId); + } + + internal bool IsInsideOf(int itemId, int ballId) + { + return _insideOfs.ContainsKey(itemId) && _insideOfs[itemId].IsSet(GetBitIndex(ballId)); + } + + internal bool IsOutsideOf(int itemId, int ballId) => !IsInsideOf(itemId, ballId); + + private void ClearItems(int itemId) + { + if (_insideOfs[itemId].GetBits(0, 64) == 0L) { + _insideOfs.Remove(itemId); + } + } + + private void ClearBitIndex(int ballId) + { + var maps = _insideOfs.GetValueArray(Allocator.TempJob); + var index = GetBitIndex(ballId); + foreach (var ballIndices in maps) { + if (!ballIndices.IsSet(index)) { + continue; + } + maps.Dispose(); + return; + } + _bitLookup.Remove(ballId); + } + + private int GetBitIndex(int ballId) + { + if (_bitLookup.ContainsKey(ballId)) { + return _bitLookup[ballId]; + } + + var indices = _bitLookup.GetValueArray(Allocator.TempJob); + for (var i = 0; i < 64; i++) { + if (indices.Contains(i)) { + continue; + } + _bitLookup[ballId] = i; + indices.Dispose(); + return i; + } + throw new IndexOutOfRangeException(); + } + + + public void Dispose() + { + _bitLookup.Dispose(); + _insideOfs.Dispose(); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs.meta new file mode 100644 index 000000000..95c048567 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 39439753f2f64ab3ace90deff7a74ae7 +timeCreated: 1681344266 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs index cfa2e9aaf..a9b831131 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs @@ -19,7 +19,7 @@ namespace VisualPinball.Unity { - public static class PhysicsColliderExtensions + public static partial class PhysicsColliderExtensions { internal static int GetId(this BlobAssetReference colliders, int index) => colliders.Value.Colliders[index].Value.Id; @@ -41,5 +41,14 @@ internal static unsafe ref PlaneCollider GetPlaneCollider(this ref BlobAssetRefe return ref UnsafeUtility.AsRef(planeCollider); } } + + internal static unsafe ref LineCollider GetLineCollider(this ref BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var lineCollider = (LineCollider*) cPtr; + return ref UnsafeUtility.AsRef(lineCollider); + } + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index e8e778305..a4e51c66d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -26,6 +26,8 @@ namespace VisualPinball.Unity public struct PhysicsCycle : IDisposable { private NativeList _contacts; + + [NativeDisableParallelForRestriction] private NativeList _overlappingColliders; public PhysicsCycle(Allocator a) @@ -34,8 +36,10 @@ public PhysicsCycle(Allocator a) _overlappingColliders = new NativeList(a); } - internal void Simulate(float dTime, ref PhysicsState state, in NativeOctree octree, - ref BlobAssetReference colliders, ref NativeList balls, ref NativeQueue.ParallelWriter events) + internal void Simulate(float dTime, ref PhysicsState state, in NativeOctree octree, + ref BlobAssetReference colliders, ref NativeList balls, + ref InsideOfs insideOfs, + ref NativeQueue.ParallelWriter events) { var staticCounts = PhysicsConstants.StaticCnts; @@ -62,7 +66,8 @@ internal void Simulate(float dTime, ref PhysicsState state, in NativeOctree PhysicsStaticBroadPhase.FindOverlaps(in octree, in ball, ref _overlappingColliders); // static narrow phase - PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, in _overlappingColliders, ref colliders, ref _contacts); + PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, in _overlappingColliders, ref colliders, + ref insideOfs, ref _contacts); // write ball back balls[i] = ball; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index fc0f4bc41..fc146e243 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -37,7 +37,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeList _balls; [NonSerialized] private NativeQueue _eventQueue; [NonSerialized] private BlobAssetReference _colliders; - + [NonSerialized] private InsideOfs _insideOfs; [NonSerialized] private readonly Dictionary _ballLookup = new(); private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); @@ -49,12 +49,13 @@ private void Start() // init state _physicsState = new NativeArray(1, Allocator.Persistent); _physicsState[0] = new PhysicsState(NowUsec, GetComponent()); + _insideOfs = new InsideOfs(Allocator.Persistent); // create static octree var sw = Stopwatch.StartNew(); var colliderItems = GetComponentsInChildren(); - Debug.Log($"Found {colliderItems.Length} collider items."); + Debug.Log($"Found {colliderItems.Length} collidable items."); var managedColliders = new List(); foreach (var colliderItem in colliderItems) { colliderItem.GetColliders(player, managedColliders, 0); @@ -100,6 +101,7 @@ private void Update() Octree = _octree, Colliders = _colliders, Balls = _balls, + InsideOfs = _insideOfs, Events = events, }; @@ -120,6 +122,7 @@ private void OnDestroy() _eventQueue.Dispose(); _balls.Dispose(); _colliders.Dispose(); + _insideOfs.Dispose(); } } @@ -147,6 +150,7 @@ internal struct UpdatePhysicsJob : IJob public NativeOctree Octree; public BlobAssetReference Colliders; public NativeList Balls; + public InsideOfs InsideOfs; public NativeQueue.ParallelWriter Events; public void Execute() @@ -155,7 +159,6 @@ public void Execute() var state = PhysicsState[0]; var cycle = new PhysicsCycle(Allocator.Temp); - while (state.CurPhysicsFrameTime < InitialTimeUsec) { var timeMsec = (uint)((state.CurPhysicsFrameTime - state.StartTimeUsec) / 1000); @@ -169,7 +172,7 @@ public void Execute() } // simulate cycle - cycle.Simulate(physicsDiffTime, ref state, in Octree, ref Colliders, ref Balls, ref Events); + cycle.Simulate(physicsDiffTime, ref state, in Octree, ref Colliders, ref Balls, ref InsideOfs, ref Events); state.CurPhysicsFrameTime = state.NextPhysicsFrameTime; state.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 8292729c2..3bdb18c53 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -38,9 +38,7 @@ internal static void Collide(float hitTime, ref BallData ball, ref BlobAssetRefe PerfMarker.Begin(); - var collEvent = ball.CollisionEvent; Collide(ref ball, ref colliders, ref random, ref events); - ball.CollisionEvent = collEvent; // remove trial hit object pointer ball.CollisionEvent.ClearCollider(); @@ -54,6 +52,9 @@ private static void Collide(ref BallData ball, ref BlobAssetReference. +// ReSharper disable ForCanBeConvertedToForeach + using Unity.Collections; using Unity.Entities; using Unity.Profiling; @@ -24,17 +26,23 @@ public static class PhysicsStaticNarrowPhase { private static readonly ProfilerMarker PerfMarker = new("PhysicsStaticNarrowPhase"); - internal static void FindNextCollision(float hitTime, ref BallData ball, in NativeList overlappingColliders, - ref BlobAssetReference colliders, ref NativeList contacts) + internal static void FindNextCollision( + float hitTime, + ref BallData ball, + in NativeList overlappingColliders, + ref BlobAssetReference colliders, + ref InsideOfs insideOfs, + ref NativeList contacts) { PerfMarker.Begin(); // init contacts and event ball.CollisionEvent.ClearCollider(hitTime); // search upto current hit time - foreach (var colliderId in overlappingColliders) { + for (var i = 0; i < overlappingColliders.Length; i++) { + var colliderId = overlappingColliders[i]; var newCollEvent = new CollisionEventData(); - var newTime = HitTest(ref ball, colliderId, ref colliders, ref contacts); + var newTime = HitTest(ref ball, ref newCollEvent, colliderId, ref colliders, ref insideOfs, ref contacts); SaveCollisions(ref ball, ref newCollEvent, ref contacts, colliderId, newTime); } @@ -46,14 +54,18 @@ internal static void FindNextCollision(float hitTime, ref BallData ball, in Nati PerfMarker.End(); } - private static float HitTest(ref BallData ball, int colliderId, ref BlobAssetReference colliders, ref NativeList contacts) + private static float HitTest(ref BallData ball, ref CollisionEventData collEvent, int colliderId, ref BlobAssetReference colliders, + ref InsideOfs insideOfs, + ref NativeList contacts) { - ref var collEvent = ref ball.CollisionEvent; var hitTime = -1f; switch (colliders.GetType(colliderId)) { case ColliderType.Plane: hitTime = colliders.GetPlaneCollider(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); break; + case ColliderType.Line: + hitTime = colliders.GetLineCollider(colliderId).HitTest(ref collEvent, ref insideOfs, ref ball, ball.CollisionEvent.HitTime); + break; } ball.CollisionEvent = collEvent; return hitTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs index 6d4bd4993..8f2940720 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using Unity.Mathematics; @@ -67,13 +68,13 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray insideOfs, in BallData ball, float dTime) + public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallData ball, float dTime) { // normal face, lateral, rigid return HitTestBasicRadius(ref collEvent, ref insideOfs, ball, dTime, true, true, true); } - public float HitTestBasicRadius(ref CollisionEventData collEvent, ref DynamicBuffer insideOfs, in BallData ball, float dTime, bool direction, bool lateral, bool rigid) + public float HitTestBasicRadius(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallData ball, float dTime, bool direction, bool lateral, bool rigid) { // todo IsEnabled if (/*!IsEnabled || */ball.IsFrozen) { @@ -129,7 +130,7 @@ public float HitTestBasicRadius(ref CollisionEventData collEvent, ref DynamicBuf // Kicker is special.. handle ball stalled on kicker, commonly hit while receding, knocking back into kicker pocket if (isKicker && bnd <= 0 && bnd >= -Radius && a < PhysicsConstants.ContactVel * PhysicsConstants.ContactVel/* && ball.Hit.IsRealBall()*/) { - BallData.SetOutsideOf(ref insideOfs, _header.ItemId); + insideOfs.SetOutsideOf(_header.ItemId, ball.Id); } // contact positive possible in future ... objects Negative in contact now @@ -149,13 +150,13 @@ public float HitTestBasicRadius(ref CollisionEventData collEvent, ref DynamicBuf hitTime = math.max(0.0f, (float) (-bnd / bnv)); } - } else if (isKickerOrTrigger /*&& ball.Hit.IsRealBall()*/ && bnd < 0 == BallData.IsOutsideOf(in insideOfs, in _header.ItemId)) { + } else if (isKickerOrTrigger /*&& ball.Hit.IsRealBall()*/ && bnd < 0 == insideOfs.IsOutsideOf(_header.ItemId, ball.Id)) { // triggers & kickers // here if ... ball inside and no hit set .... or ... ball outside and hit set if (math.abs(bnd - Radius) < 0.05) { // if ball appears in center of trigger, then assumed it was gen"ed there - BallData.SetInsideOf(ref insideOfs, _header.ItemId); // special case for trigger overlaying a kicker + insideOfs.SetInsideOf(_header.ItemId, ball.Id); // special case for trigger overlaying a kicker } else { // this will add the ball to the trigger space without a Hit diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 817c91384..9061d040e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -90,11 +90,11 @@ internal static unsafe float HitTest(ref Collider coll, ref CollisionEventData c { case ColliderType.Bumper: case ColliderType.Circle: - return ((CircleCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); +// return ((CircleCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); case ColliderType.Gate: - return ((GateCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); +// return ((GateCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); case ColliderType.Line: - return ((LineCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); +// return ((LineCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); case ColliderType.LineZ: return ((LineZCollider*) collider)->HitTest(ref collEvent, in ball, dTime); case ColliderType.Line3D: @@ -104,14 +104,14 @@ internal static unsafe float HitTest(ref Collider coll, ref CollisionEventData c case ColliderType.Plane: return ((PlaneCollider*) collider)->HitTest(ref collEvent, in ball, dTime); case ColliderType.Spinner: - return ((SpinnerCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); +// return ((SpinnerCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); case ColliderType.Triangle: - return ((TriangleCollider*) collider)->HitTest(ref collEvent, in insideOf, in ball, dTime); +// return ((TriangleCollider*) collider)->HitTest(ref collEvent, in insideOf, in ball, dTime); case ColliderType.KickerCircle: case ColliderType.TriggerCircle: - return ((CircleCollider*) collider)->HitTestBasicRadius(ref collEvent, ref insideOf, in ball, dTime, false, false, false); +// return ((CircleCollider*) collider)->HitTestBasicRadius(ref collEvent, ref insideOf, in ball, dTime, false, false, false); case ColliderType.TriggerLine: - return ((LineCollider*) collider)->HitTestBasic(ref collEvent, ref insideOf, in ball, dTime, false, false, false); +// return ((LineCollider*) collider)->HitTestBasic(ref collEvent, ref insideOf, in ball, dTime, false, false, false); case ColliderType.Plunger: throw new InvalidOperationException("ColliderType.Plunger must be hit-tested separately!"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index 15ff706aa..573fdf682 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -18,8 +18,10 @@ using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using Unity.Mathematics; +using UnityEngine; using VisualPinball.Engine.Common; using VisualPinball.Engine.VPT; +using Random = Unity.Mathematics.Random; namespace VisualPinball.Unity { @@ -42,6 +44,8 @@ internal struct LineCollider : ICollider public float V1y { set => V1.y = value; } public float V2y { set => V2.y = value; } + + public override string ToString() => $"LineCollider[{_header.ItemId}] ({V1.x}/{V1.y}@{ZLow}) -> ({V2.x}/{V2.y}@{ZHigh}) at ({Normal.x}/{Normal.y}), len: {_length}"; public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( math.min(V1.x, V2.x), @@ -88,29 +92,25 @@ public void CalcNormal() #region Narrowphase public static float HitTest(ref CollisionEventData collEvent, - ref DynamicBuffer insideOfs, in LineCollider coll, in BallData ball, float dTime) + ref InsideOfs insideOfs, in LineCollider coll, ref BallData ball, float dTime) { - return HitTestBasic(ref collEvent, ref insideOfs, in coll, ball, dTime, true, true, true); // normal face, lateral, rigid + return HitTestBasic(ref collEvent, ref insideOfs, in coll, ref ball, dTime, true, true, true); // normal face, lateral, rigid } public float HitTest(ref CollisionEventData collEvent, - ref DynamicBuffer insideOfs, in BallData ball, float dTime) + ref InsideOfs insideOfs, ref BallData ball, float dTime) { - return HitTestBasic(ref collEvent, ref insideOfs, in this, ball, dTime, true, true, true); // normal face, lateral, rigid + return HitTestBasic(ref collEvent, ref insideOfs, in this, ref ball, dTime, true, true, true); // normal face, lateral, rigid } - public float HitTestBasic(ref CollisionEventData collEvent, ref DynamicBuffer insideOfs, in BallData ball, float dTime, + public float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs insideOfs, ref BallData ball, float dTime, bool direction, bool lateral, bool rigid) { - return HitTestBasic(ref collEvent, ref insideOfs, in this, ball, dTime, direction, lateral, rigid); + return HitTestBasic(ref collEvent, ref insideOfs, in this, ref ball, dTime, direction, lateral, rigid); } - public static float HitTestBasic(ref CollisionEventData collEvent, ref DynamicBuffer insideOfs, in LineCollider coll, in BallData ball, float dTime, bool direction, bool lateral, bool rigid) + public static float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in LineCollider coll, ref BallData ball, float dTime, bool direction, bool lateral, bool rigid) { - // if (!IsEnabled || ball.State.IsFrozen) { - // return -1.0f; - // } - // ball velocity var ballVx = ball.Velocity.x; var ballVy = ball.Velocity.y; @@ -171,7 +171,7 @@ public static float HitTestBasic(ref CollisionEventData collEvent, ref DynamicBu /*todo || !ball.m_vpVolObjs*/ // it's a trigger, so test: || math.abs(bnd) >= ball.Radius * 0.5f // not too close ... nor too far away - || inside == BallData.IsInsideOf(in insideOfs, coll.ItemId)) // ...ball outside and hit set or ball inside and no hit set + || inside == insideOfs.IsInsideOf(coll.ItemId, ball.Id)) // ...ball outside and hit set or ball inside and no hit set { return -1.0f; } @@ -216,6 +216,10 @@ public static float HitTestBasic(ref CollisionEventData collEvent, ref DynamicBu collEvent.HitNormal.z = 0f; collEvent.HitDistance = bnd; // actual contact distance ... + if (collEvent.HitNormal is { x: 0, y: 0, z: 0 }) { + Debug.Log("Hit normal set to zero by line collider."); + } + // check for contact collEvent.IsContact = math.abs(bnv) <= PhysicsConstants.ContactVel && math.abs(bnd) <= PhysicsConstants.PhysTouch; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs index 925ebbf54..33f6f5444 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs @@ -83,15 +83,15 @@ private void CalcNormal() #region Narrowphase - public float HitTest(ref CollisionEventData collEvent, ref DynamicBuffer insideOfs, in BallData ball, float dTime) + public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, ref BallData ball, float dTime) { - return HitTest(ref collEvent, ref this, ref insideOfs, in ball, dTime); + return HitTest(ref collEvent, ref this, ref insideOfs, ref ball, dTime); } - private static float HitTest(ref CollisionEventData collEvent, ref LineSlingshotCollider coll, ref DynamicBuffer insideOfs, in BallData ball, float dTime) + private static float HitTest(ref CollisionEventData collEvent, ref LineSlingshotCollider coll, ref InsideOfs insideOfs, ref BallData ball, float dTime) { ref var lineColl = ref UnsafeUtility.As(ref coll); - return LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in lineColl, in ball, dTime, true, true, true); + return LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in lineColl, ref ball, dTime, true, true, true); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index 2d91bc3d9..000b171a8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -17,7 +17,9 @@ using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using Unity.Mathematics; +using UnityEngine; using VisualPinball.Engine.Common; +using Random = Unity.Mathematics.Random; namespace VisualPinball.Unity { @@ -32,7 +34,8 @@ internal struct PlaneCollider : ICollider private readonly float3 _normal; private readonly float _distance; - public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb(float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue)); + //public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb(0, 1500f, 3000, 0, -50, 1000)); + public ColliderBounds Bounds => new(_header.ItemId, _header.Id, new Aabb(float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue)); public PlaneCollider(float3 normal, float distance, ColliderInfo info) : this() { @@ -52,11 +55,8 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray $"PlaneCollider[{_header.ItemId}] {_distance} at ({_normal.x}/{_normal.y}/{_normal.z})"; #region Narrowphase @@ -85,6 +85,10 @@ public float HitTest(ref CollisionEventData collEvent, in BallData ball, float d collEvent.HitNormal = _normal; collEvent.HitOrgNormalVelocity = bnv; // remember original normal velocity collEvent.HitDistance = bnd; + + if (collEvent.HitNormal is { x: 0, y: 0, z: 0 }) { + Debug.Log("Hit normal set to zero by plane collider."); + } // hit time is ignored for contacts return 0.0f; @@ -108,7 +112,11 @@ public float HitTest(ref CollisionEventData collEvent, in BallData ball, float d collEvent.HitNormal = _normal; collEvent.HitDistance = bnd; // actual contact distance - + + if (collEvent.HitNormal is { x: 0, y: 0, z: 0 }) { + Debug.Log("Hit normal set to zero by plane collider."); + } + return hitTime; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs index 586fe9fc1..c60307a7d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs @@ -35,6 +35,8 @@ internal struct TriangleCollider : ICollider private readonly float3 _normal; public float3 Normal() => _normal; + + public override string ToString() => $"TriangleCollider[{_header.ItemId}] ({Rgv0.x}/{Rgv0.y}/{Rgv0.z}), ({Rgv1.x}/{Rgv1.y}/{Rgv1.z}), ({Rgv2.x}/{Rgv2.y}/{Rgv2.z}) at ({_normal.x}/{_normal.y/_normal.z})"; public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( math.min(Rgv0.x, math.min(Rgv1.x, Rgv2.x)), @@ -80,7 +82,7 @@ public static bool IsDegenerate(float3 rg0, float3 rg1, float3 rg2) #region Narrowphase - public float HitTest(ref CollisionEventData collEvent, in DynamicBuffer insideOfs, in BallData ball, float dTime) + public float HitTest(ref CollisionEventData collEvent, in InsideOfs insideOfs, in BallData ball, float dTime) { // if (!this.isEnabled) { // return -1.0; @@ -155,7 +157,7 @@ public float HitTest(ref CollisionEventData collEvent, in DynamicBuffer 0; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs index 2cf46d3a5..1f189c746 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs @@ -178,10 +178,10 @@ in spinnerStaticData ? GetComponent(coll.ItemId) : new TriggerAnimationData(); - TriggerCollider.Collide( - ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, - in ballId, in coll - ); + // TriggerCollider.Collide( + // ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, + // in ballId, in coll + // ); if (HasComponent(coll.ItemId)) { if (triggerAnimationData.UnHitEvent) { @@ -208,9 +208,9 @@ in spinnerStaticData var legacyMode = KickerCollider.ForceLegacyMode || kickerStaticData.LegacyMode; // ReSharper disable once ConditionIsAlwaysTrueOrFalse var kickerMeshData = !legacyMode ? GetComponent(coll.ItemId) : default; - KickerCollider.Collide(ref ballData, ref events, ref insideOfs, ref kickerCollisionData, - in kickerStaticData, in kickerMeshData, in collEvent, coll.ItemId, in ballId - ); + // KickerCollider.Collide(ref ballData, ref events, ref insideOfs, ref kickerCollisionData, + // in kickerStaticData, in kickerMeshData, in collEvent, coll.ItemId, in ballId + // ); SetComponent(coll.ItemId, kickerCollisionData); break; } @@ -251,10 +251,10 @@ in spinnerStaticData ? GetComponent(coll.ItemId) : new TriggerAnimationData(); - TriggerCollider.Collide( - ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, - in ballId, in coll - ); + // TriggerCollider.Collide( + // ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, + // in ballId, in coll + // ); if (HasComponent(coll.ItemId)) { if (triggerAnimationData.UnHitEvent) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs index 57d788565..5c6bb151d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs @@ -94,7 +94,7 @@ protected override void OnUpdate() switch (coll.Type) { case ColliderType.LineSlingShot: - newTime = ((LineSlingshotCollider*) collider)->HitTest(ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); +// newTime = ((LineSlingshotCollider*) collider)->HitTest(ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); break; case ColliderType.Flipper: @@ -106,10 +106,10 @@ protected override void OnUpdate() var flipperMovementData = GetComponent(coll.ItemId); var flipperMaterialData = GetComponent(coll.ItemId); var flipperTricksData = GetComponent(coll.ItemId); - newTime = ((FlipperCollider*)collider)->HitTest( - ref newCollEvent, ref insideOfs, ref flipperHitData, - in flipperMovementData, in flipperTricksData, in flipperMaterialData, in ballData, collEvent.HitTime - ); + // newTime = ((FlipperCollider*)collider)->HitTest( + // ref newCollEvent, ref insideOfs, ref flipperHitData, + // in flipperMovementData, in flipperTricksData, in flipperMaterialData, in ballData, collEvent.HitTime + // ); SetComponent(coll.ItemId, flipperHitData); } @@ -123,10 +123,10 @@ protected override void OnUpdate() var plungerColliderData = GetComponent(coll.ItemId); var plungerStaticData = GetComponent(coll.ItemId); var plungerMovementData = GetComponent(coll.ItemId); - newTime = ((PlungerCollider*)collider)->HitTest( - ref newCollEvent, ref insideOfs, ref plungerMovementData, - in plungerColliderData, in plungerStaticData, in ballData, collEvent.HitTime - ); + // newTime = ((PlungerCollider*)collider)->HitTest( + // ref newCollEvent, ref insideOfs, ref plungerMovementData, + // in plungerColliderData, in plungerStaticData, in ballData, collEvent.HitTime + // ); SetComponent(coll.ItemId, plungerMovementData); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs index 72b778f45..4beb4be70 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs @@ -151,36 +151,6 @@ the angular velocity used here is not the angular velocity that the ball has (wh */ } - public static void SetOutsideOf(ref DynamicBuffer insideOfs, in int itemId) - { - for (var i = 0; i < insideOfs.Length; i++) { - if (insideOfs[i].Value == itemId) { - insideOfs.RemoveAt(i); - return; - } - } - } - - public static void SetInsideOf(ref DynamicBuffer insideOfs, int itemId) - { - insideOfs.Add(new BallInsideOfBufferElement { Value = itemId }); - } - - public static bool IsOutsideOf(in DynamicBuffer insideOfs, in int itemId) - { - return !IsInsideOf(in insideOfs, in itemId); - } - - public static bool IsInsideOf(in DynamicBuffer insideOfs, in int itemId) - { - for (var i = 0; i < insideOfs.Length; i++) { - if (insideOfs[i].Value == itemId) { - return true; - } - } - return false; - } - public override string ToString() { return $"Ball{Id} ({Position.x}/{Position.y})"; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index b30944d41..498ba3b1f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -19,9 +19,11 @@ using System; using System.Collections.Generic; using System.Linq; +using NativeTrees; using Unity.Entities; using Unity.Mathematics; using Unity.Collections; +using Unity.Jobs; using UnityEngine; using UnityEngine.Profiling; using VisualPinball.Engine.VPT; @@ -45,6 +47,9 @@ public abstract class ColliderComponent : SubComponent(); + api.CreateColliders(colliders, 0.1f); + + var playfieldBounds = GetComponentInChildren().Bounds; + var octree = new NativeOctree(playfieldBounds, 32, 10, Allocator.Persistent); + + var allocateColliderJob = new ColliderAllocationJob(colliders); + allocateColliderJob.Run(); + var colliderBlob = allocateColliderJob.BlobAsset[0]; + allocateColliderJob.Dispose(); + + var populateJob = new PopulatePhysicsJob { + Colliders = colliderBlob, + Octree = octree, + }; + populateJob.Run(); + Gizmos.color = Color.yellow; + octree.DrawGizmos(); + } if (showColliders) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs index aade98670..43c434157 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs @@ -152,7 +152,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray insideOfs, + public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, ref FlipperHitData hitData, in FlipperMovementData movementData, in FlipperTricksData tricks, in FlipperStaticData matData, in BallData ball, float dTime) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs index 368f25e90..cd1a6d4f3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs @@ -58,21 +58,21 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray insideOfs, in BallData ball, float dTime) + public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, ref BallData ball, float dTime) { // todo // if (!this.isEnabled) { // return -1.0; // } - var hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg0, in ball, dTime, false, true, false); // any face, lateral, non-rigid + var hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg0, ref ball, dTime, false, true, false); // any face, lateral, non-rigid if (hitTime >= 0) { // signal the Collide() function that the hit is on the front or back side collEvent.HitFlag = false; return hitTime; } - hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg1, in ball, dTime, false, true, false); // any face, lateral, non-rigid + hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg1, ref ball, dTime, false, true, false); // any face, lateral, non-rigid if (hitTime >= 0) { collEvent.HitFlag = true; return hitTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs index 6a9eda33b..b1655003d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs @@ -32,7 +32,7 @@ internal static class KickerCollider public const bool ForceLegacyMode = true; public static void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, - ref DynamicBuffer insideOfs, ref KickerCollisionData collData, + ref InsideOfs insideOfs, ref KickerCollisionData collData, in KickerStaticData staticData, in ColliderMeshData meshData, in CollisionEventData collEvent, in int itemId, in int ballId) { @@ -47,7 +47,7 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle var hitBit = collEvent.HitFlag; // check if kicker in ball's volume set - var isBallInside = BallData.IsInsideOf(in insideOfs, itemId); + var isBallInside = insideOfs.IsInsideOf(itemId, ballId); // New or (Hit && !Vol || UnHit && Vol) if (hitBit == isBallInside) { @@ -83,7 +83,7 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle ball.IsFrozen = !staticData.FallThrough; if (ball.IsFrozen) { - BallData.SetInsideOf(ref insideOfs, itemId); // add kicker to ball's volume set + insideOfs.SetInsideOf(itemId, ball.Id); // add kicker to ball's volume set collData.BallId = ballId; collData.LastCapturedBallId = ballId; } @@ -115,7 +115,7 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle } else { // exiting kickers volume // remove kicker to ball's volume set - BallData.SetOutsideOf(ref insideOfs, itemId); + insideOfs.SetOutsideOf(itemId, ball.Id); events.Enqueue(new EventData(EventId.HitEventsUnhit, itemId, ballId, true)); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs index dd4cfc70a..6357d66ba 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs @@ -102,14 +102,14 @@ protected override void CreateColliders(List colliders, float margin) )); } - // glass: - var rgv3D = new[] { - new float3(MainComponent.Left, MainComponent.Top, MainComponent.GlassHeight), - new float3(MainComponent.Right, MainComponent.Top, MainComponent.GlassHeight), - new float3(MainComponent.Right, MainComponent.Bottom, MainComponent.GlassHeight), - new float3(MainComponent.Left, MainComponent.Bottom, MainComponent.GlassHeight) - }; - ColliderUtils.Generate3DPolyColliders(rgv3D, info, colliders); + // glass (it's handled by the plane) + // var rgv3D = new[] { + // new float3(MainComponent.Left, MainComponent.Top, MainComponent.GlassHeight), + // new float3(MainComponent.Right, MainComponent.Top, MainComponent.GlassHeight), + // new float3(MainComponent.Right, MainComponent.Bottom, MainComponent.GlassHeight), + // new float3(MainComponent.Left, MainComponent.Bottom, MainComponent.GlassHeight) + // }; + // ColliderUtils.Generate3DPolyColliders(rgv3D, info, colliders); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs index 38412166e..acdd53139 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using Unity.Mathematics; @@ -76,8 +77,8 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray insideOfs, - ref PlungerMovementData movementData, in PlungerColliderData colliderData, in PlungerStaticData staticData, in BallData ball, float dTime) + public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, + ref PlungerMovementData movementData, in PlungerColliderData colliderData, in PlungerStaticData staticData, ref BallData ball, float dTime) { var hitTime = dTime; //start time var isHit = false; @@ -94,16 +95,16 @@ public float HitTest(ref CollisionEventData collEvent, ref DynamicBuffer. +using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using Unity.Mathematics; @@ -74,19 +75,19 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray insideOfs, in BallData ball, float dTime) + public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, ref BallData ball, float dTime) { // todo // if (!m_enabled) return -1.0f; - var hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg0, in ball, dTime, false, true, false); // any face, lateral, non-rigid + var hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg0, ref ball, dTime, false, true, false); // any face, lateral, non-rigid if (hitTime >= 0.0f) { // signal the Collide() function that the hit is on the front or back side collEvent.HitFlag = true; return hitTime; } - hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg1, in ball, dTime, false, true, false); // any face, lateral, non-rigid + hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg1, ref ball, dTime, false, true, false); // any face, lateral, non-rigid if (hitTime >= 0.0f) { // signal the Collide() function that the hit is on the front or back side collEvent.HitFlag = false; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs index aaac44852..0cc33acf4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Entities; using VisualPinball.Engine.Common; using VisualPinball.Engine.Game; @@ -24,23 +23,23 @@ namespace VisualPinball.Unity internal static class TriggerCollider { public static void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, - ref CollisionEventData collEvent, ref DynamicBuffer insideOfs, - ref TriggerAnimationData animationData, in int ballId, in Collider coll) + ref CollisionEventData collEvent, ref InsideOfs insideOfs, + ref TriggerAnimationData animationData, in Collider coll) { - var insideOf = BallData.IsInsideOf(in insideOfs, coll.ItemId); + var insideOf = insideOfs.IsInsideOf(coll.ItemId, ball.Id); if (collEvent.HitFlag == insideOf) { // Hit == NotAlreadyHit ball.Position += PhysicsConstants.StaticTime * ball.Velocity; // move ball slightly forward if (!insideOf) { - BallData.SetInsideOf(ref insideOfs, coll.ItemId); + insideOfs.SetInsideOf(coll.ItemId, ball.Id); animationData.HitEvent = true; - events.Enqueue(new EventData(EventId.HitEventsHit, coll.ItemId, ballId, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, coll.ItemId, ball.Id, true)); } else { - BallData.SetOutsideOf(ref insideOfs, coll.ItemId); + insideOfs.SetOutsideOf(coll.ItemId, ball.Id); animationData.UnHitEvent = true; - events.Enqueue(new EventData(EventId.HitEventsUnhit, coll.ItemId, ballId, true)); + events.Enqueue(new EventData(EventId.HitEventsUnhit, coll.ItemId, ball.Id, true)); } } } From 3ae194e0d81d7c124c3524e63aed358f4e7425c9 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 1 Oct 2023 00:13:32 +0200 Subject: [PATCH 049/159] jobs: Fix collision loop. --- .../VisualPinball.Unity/Common/DebugLogger.cs | 22 ++++++++++++++++ .../Common/DebugLogger.cs.meta | 3 +++ .../Game/PhysicsColliderExtensions.cs | 9 +++++++ .../VisualPinball.Unity/Game/PhysicsEngine.cs | 26 ++++++++++++------- .../Game/PhysicsStaticNarrowPhase.cs | 3 +-- .../VisualPinball.Unity/Game/Player.cs | 1 + .../VisualPinball.Unity/VPT/Ball/BallData.cs | 2 -- .../VPT/Ball/BallDisplacementPhysics.cs | 3 --- .../VPT/Ball/BallMovementPhysics.cs | 7 ++--- .../VPT/Ball/BallVelocityPhysics.cs | 6 ++++- 10 files changed, 59 insertions(+), 23 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Common/DebugLogger.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Common/DebugLogger.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Common/DebugLogger.cs b/VisualPinball.Unity/VisualPinball.Unity/Common/DebugLogger.cs new file mode 100644 index 000000000..8428d9583 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Common/DebugLogger.cs @@ -0,0 +1,22 @@ +using System; +using System.IO; + +namespace VisualPinball.Unity +{ + public static class DebugLogger + { + private const string FileName = @"C:\Temp\physdebug\vpe-2022.log"; + + public static void ClearLog() + { + if (File.Exists(FileName)) { + File.Delete(FileName); + } + } + + public static void Log(string msg) + { + File.AppendAllText(FileName, msg + Environment.NewLine); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Common/DebugLogger.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Common/DebugLogger.cs.meta new file mode 100644 index 000000000..3630278de --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Common/DebugLogger.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2187d14cf7304e5b8124cf377c7b24e0 +timeCreated: 1695983818 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs index a9b831131..6c159be69 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs @@ -50,5 +50,14 @@ internal static unsafe ref LineCollider GetLineCollider(this ref BlobAssetRefere return ref UnsafeUtility.AsRef(lineCollider); } } + + // internal static unsafe ref T GetCollider(this ref BlobAssetReference colliders, int index) where T : struct + // { + // ref var coll = ref colliders.Value.Colliders[index].Value; + // fixed (Collider* cPtr = &coll) { + // var collider = (T*) cPtr; + // return ref UnsafeUtility.AsRef(collider); + // } + // } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index fc146e243..c4b93dcff 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -60,13 +60,10 @@ private void Start() foreach (var colliderItem in colliderItems) { colliderItem.GetColliders(player, managedColliders, 0); } - + // allocate colliders - var allocateColliderJob = new ColliderAllocationJob(managedColliders); - allocateColliderJob.Run(); - _colliders = allocateColliderJob.BlobAsset[0]; - allocateColliderJob.Dispose(); - + _colliders = AllocateColliders(managedColliders); + // create octree var elapsedMs = sw.Elapsed.TotalMilliseconds; var playfieldBounds = GetComponentInChildren().Bounds; @@ -75,7 +72,7 @@ private void Start() sw.Restart(); var populateJob = new PopulatePhysicsJob { Colliders = _colliders, - Octree = _octree, + Octree = _octree, }; populateJob.Run(); _octree = populateJob.Octree; @@ -92,6 +89,15 @@ private void Start() _eventQueue = new NativeQueue(Allocator.Persistent); } + private static BlobAssetReference AllocateColliders(IEnumerable managedColliders) + { + var allocateColliderJob = new ColliderAllocationJob(managedColliders); + allocateColliderJob.Run(); + var colliders = allocateColliderJob.BlobAsset[0]; + allocateColliderJob.Dispose(); + return colliders; + } + private void Update() { var events = _eventQueue.AsParallelWriter(); @@ -159,19 +165,19 @@ public void Execute() var state = PhysicsState[0]; var cycle = new PhysicsCycle(Allocator.Temp); - while (state.CurPhysicsFrameTime < InitialTimeUsec) + while (state.CurPhysicsFrameTime < InitialTimeUsec) // loop here until current (real) time matches the physics (simulated) time { var timeMsec = (uint)((state.CurPhysicsFrameTime - state.StartTimeUsec) / 1000); var physicsDiffTime = (float)((state.NextPhysicsFrameTime - state.CurPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); - // update velocities + // update velocities - always on integral physics frame boundary (spinner, gate, flipper, plunger, ball) for (var i = 0; i < Balls.Length; i++) { var ball = Balls[i]; BallVelocityPhysics.UpdateVelocities(state.Gravity, ref ball); Balls[i] = ball; } - // simulate cycle + // primary physics loop cycle.Simulate(physicsDiffTime, ref state, in Octree, ref Colliders, ref Balls, ref InsideOfs, ref Events); state.CurPhysicsFrameTime = state.NextPhysicsFrameTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index 1d34ac1ff..4137de2c6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -53,7 +53,7 @@ internal static void FindNextCollision( PerfMarker.End(); } - + private static float HitTest(ref BallData ball, ref CollisionEventData collEvent, int colliderId, ref BlobAssetReference colliders, ref InsideOfs insideOfs, ref NativeList contacts) @@ -67,7 +67,6 @@ private static float HitTest(ref BallData ball, ref CollisionEventData collEvent hitTime = colliders.GetLineCollider(colliderId).HitTest(ref collEvent, ref insideOfs, ref ball, ball.CollisionEvent.HitTime); break; } - ball.CollisionEvent = collEvent; return hitTime; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 69dca1323..89b9b8d0e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -139,6 +139,7 @@ public Player() private void Awake() { + DebugLogger.ClearLog(); _tableComponent = GetComponent(); _playfieldComponent = GetComponentInChildren(); var engineComponent = GetComponent(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs index 4beb4be70..969908747 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs @@ -14,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System; -using Unity.Collections; using Unity.Entities; using Unity.Mathematics; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs index bdd9adf93..ed51c99b8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs @@ -32,9 +32,6 @@ internal static void UpdateDisplacements(ref BallData ball, float dTime) PerfMarker.Begin(); ball.Position += ball.Velocity * dTime; - - - //Logger.Debug($"Ball {ball.Id} Position = {ball.Position}"); var inertia = ball.Inertia; var mat3 = CreateSkewSymmetric(ball.AngularMomentum / inertia); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs index 03370f86a..77ec75199 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs @@ -14,13 +14,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; -using Unity.Mathematics; using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -using Physics = UnityEngine.Physics; +using Physics = VisualPinball.Unity.Physics; namespace VisualPinballUnity { @@ -48,7 +45,7 @@ public static void Move(BallData ball, Transform ballTransform) // calculate/adapt height of ball var zHeight = !ball.IsFrozen ? ball.Position.z : ball.Position.z - ball.Radius; - ballTransform.localPosition = VisualPinball.Unity.Physics.TranslateToWorld(ball.Position.x, ball.Position.y, zHeight); + ballTransform.localPosition = Physics.TranslateToWorld(ball.Position.x, ball.Position.y, zHeight); var or = ball.BallOrientationForUnity; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs index a26a8cc97..67c554c0b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs @@ -31,6 +31,10 @@ public static void UpdateVelocities(float3 gravity, ref BallData ball) { PerfMarker.Begin(); + if (ball.IsFrozen) { + return; + } + if (ball.ManualControl) { ball.Velocity *= 0.5f; // Null out most of the X/Y velocity, want a little bit so the ball can sort of find its way out of obstacles. ball.Velocity += new float3( @@ -39,7 +43,7 @@ public static void UpdateVelocities(float3 gravity, ref BallData ball) -2.0f ); } else { - ball.Velocity += gravity * (float)PhysicsConstants.PhysFactor; + ball.Velocity += (float)PhysicsConstants.PhysFactor * gravity; } PerfMarker.End(); From d22ac83b1d94ed39ec459cd6fd3751b3bbdf05fd Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 1 Oct 2023 00:38:09 +0200 Subject: [PATCH 050/159] jobs: Minor refactor. --- .../Game/PhysicsColliderExtensions.cs | 13 ++------ .../Game/PhysicsStaticNarrowPhase.cs | 22 ++----------- .../Physics/Collider/ColliderRef.cs | 32 +++++++++++++++++++ .../Physics/Collider/ColliderRef.cs.meta | 3 ++ .../VPT/Ball/BallDisplacementPhysics.cs | 2 -- 5 files changed, 40 insertions(+), 32 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs index 6c159be69..9042dedcc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs @@ -33,7 +33,7 @@ internal static float GetFriction(this BlobAssetReference collider internal static Aabb GetAabb(this BlobAssetReference colliders, int index) => colliders.Value.Colliders[index].Value.Bounds().Aabb; - internal static unsafe ref PlaneCollider GetPlaneCollider(this ref BlobAssetReference colliders, int index) + internal static unsafe ref PlaneCollider GetPlaneCollider(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -42,7 +42,7 @@ internal static unsafe ref PlaneCollider GetPlaneCollider(this ref BlobAssetRefe } } - internal static unsafe ref LineCollider GetLineCollider(this ref BlobAssetReference colliders, int index) + internal static unsafe ref LineCollider GetLineCollider(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -50,14 +50,5 @@ internal static unsafe ref LineCollider GetLineCollider(this ref BlobAssetRefere return ref UnsafeUtility.AsRef(lineCollider); } } - - // internal static unsafe ref T GetCollider(this ref BlobAssetReference colliders, int index) where T : struct - // { - // ref var coll = ref colliders.Value.Colliders[index].Value; - // fixed (Collider* cPtr = &coll) { - // var collider = (T*) cPtr; - // return ref UnsafeUtility.AsRef(collider); - // } - // } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index 4137de2c6..f4db4422b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -40,10 +40,10 @@ internal static void FindNextCollision( ball.CollisionEvent.ClearCollider(hitTime); // search upto current hit time for (var i = 0; i < overlappingColliders.Length; i++) { - var colliderId = overlappingColliders[i]; var newCollEvent = new CollisionEventData(); - var newTime = HitTest(ref ball, ref newCollEvent, colliderId, ref colliders, ref insideOfs, ref contacts); - SaveCollisions(ref ball, ref newCollEvent, ref contacts, colliderId, newTime); + var colliderRef = new ColliderRef(overlappingColliders[i], ref colliders); + var newTime = colliderRef.HitTest(ref ball, ref newCollEvent, ref insideOfs, ref contacts); + SaveCollisions(ref ball, ref newCollEvent, ref contacts, colliderRef.Id, newTime); } // no negative time allowed @@ -54,22 +54,6 @@ internal static void FindNextCollision( PerfMarker.End(); } - private static float HitTest(ref BallData ball, ref CollisionEventData collEvent, int colliderId, ref BlobAssetReference colliders, - ref InsideOfs insideOfs, - ref NativeList contacts) - { - var hitTime = -1f; - switch (colliders.GetType(colliderId)) { - case ColliderType.Plane: - hitTime = colliders.GetPlaneCollider(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); - break; - case ColliderType.Line: - hitTime = colliders.GetLineCollider(colliderId).HitTest(ref collEvent, ref insideOfs, ref ball, ball.CollisionEvent.HitTime); - break; - } - return hitTime; - } - private static float HitTest(ref BallData ball, in Collider collider, ref NativeList contacts) { ref var collEvent = ref ball.CollisionEvent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs new file mode 100644 index 000000000..b2c4da6a7 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs @@ -0,0 +1,32 @@ +using Unity.Collections; +using Unity.Entities; + +namespace VisualPinball.Unity +{ + public readonly ref struct ColliderRef + { + internal readonly int Id; + private readonly BlobAssetReference _colliders; + + internal ColliderRef(int id, ref BlobAssetReference colliders) + { + _colliders = colliders; + Id = id; + } + + internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref InsideOfs insideOfs, + ref NativeList contacts) + { + var hitTime = -1f; + switch (_colliders.GetType(Id)) { + case ColliderType.Plane: + hitTime = _colliders.GetPlaneCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + break; + case ColliderType.Line: + hitTime = _colliders.GetLineCollider(Id).HitTest(ref collEvent, ref insideOfs, ref ball, ball.CollisionEvent.HitTime); + break; + } + return hitTime; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs.meta new file mode 100644 index 000000000..3ef6fabbf --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9dae49cec2cb490bbe02e99f758ceaca +timeCreated: 1696112308 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs index ed51c99b8..621f82b58 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs @@ -14,12 +14,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { From 221ce1eb0a6c470d16e7ccf46820e186f156e76d Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 1 Oct 2023 12:36:21 +0200 Subject: [PATCH 051/159] jobs: Add collision for primitives (triangle, line3d, point). --- .../Game/PhysicsColliderExtensions.cs | 27 +++++++++++++++++++ .../Game/PhysicsStaticCollision.cs | 9 +++++++ .../Physics/Collider/ColliderRef.cs | 9 +++++++ .../Physics/Collider/LineCollider.cs | 4 --- .../Physics/Collider/PlaneCollider.cs | 1 - .../Primitive/PrimitiveColliderComponent.cs | 10 ++++--- 6 files changed, 52 insertions(+), 8 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs index 9042dedcc..dcf727d34 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs @@ -50,5 +50,32 @@ internal static unsafe ref LineCollider GetLineCollider(this in BlobAssetReferen return ref UnsafeUtility.AsRef(lineCollider); } } + + internal static unsafe ref TriangleCollider GetTriangleCollider(this in BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var triangleCollider = (TriangleCollider*) cPtr; + return ref UnsafeUtility.AsRef(triangleCollider); + } + } + + internal static unsafe ref Line3DCollider GetLine3DCollider(this in BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var line3DCollider = (Line3DCollider*) cPtr; + return ref UnsafeUtility.AsRef(line3DCollider); + } + } + + internal static unsafe ref PointCollider GetPointCollider(this in BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var pointCollider = (PointCollider*) cPtr; + return ref UnsafeUtility.AsRef(pointCollider); + } + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 3bdb18c53..f645d0814 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -55,6 +55,15 @@ private static void Collide(ref BallData ball, ref BlobAssetReference new ColliderBounds(_header.ItemId, _header.Id, new Aabb(0, 1500f, 3000, 0, -50, 1000)); public ColliderBounds Bounds => new(_header.ItemId, _header.Id, new Aabb(float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue)); public PlaneCollider(float3 normal, float distance, ColliderInfo info) : this() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs index dfecc442e..cd0733444 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs @@ -16,15 +16,14 @@ // ReSharper disable InconsistentNaming -using System; -using Unity.Entities; +using System.Collections.Generic; using UnityEngine; using VisualPinball.Engine.VPT.Primitive; namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Collision/Primitive Collider")] - public class PrimitiveColliderComponent : ColliderComponent + public class PrimitiveColliderComponent : ColliderComponent, ICollidableComponent { #region Data @@ -63,5 +62,10 @@ public class PrimitiveColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); protected override IApiColliderGenerator InstantiateColliderApi(Player player) => new PrimitiveApi(gameObject, player); + + void ICollidableComponent.GetColliders(Player player, List colliders, float margin) + { + InstantiateColliderApi(player).CreateColliders(colliders, margin); + } } } From fee124bb5d41eec8d1c88892b2a4d2c767427437 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 2 Oct 2023 00:15:20 +0200 Subject: [PATCH 052/159] jobs: Add flipper collision. --- .../Game/PhysicsColliderExtensions.cs | 9 + .../VisualPinball.Unity/Game/PhysicsCycle.cs | 15 +- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 49 ++++- .../VisualPinball.Unity/Game/PhysicsState.cs | 8 +- .../Game/PhysicsStaticCollision.cs | 16 +- .../Game/PhysicsStaticNarrowPhase.cs | 5 +- .../Physics/Collider/ColliderRef.cs | 28 ++- .../Physics/Engine/DefaultPhysicsEngine.cs | 25 +-- .../VisualPinball.Unity/VPT/Ball/BallData.cs | 3 + .../VPT/Ball/BallVelocityPhysics.cs | 2 +- .../VPT/Flipper/FlipperColliderComponent.cs | 11 +- .../VPT/Flipper/FlipperComponent.cs | 27 +++ .../VPT/Flipper/FlipperDisplacementPhysics.cs | 89 +++++++++ .../FlipperDisplacementPhysics.cs.meta | 3 + .../VPT/Flipper/FlipperDisplacementSystem.cs | 4 +- .../VPT/Flipper/FlipperState.cs | 42 ++++ .../VPT/Flipper/FlipperState.cs.meta | 3 + .../VPT/Flipper/FlipperVelocityPhysics.cs | 180 ++++++++++++++++++ .../Flipper/FlipperVelocityPhysics.cs.meta | 3 + .../VPT/Flipper/FlipperVelocitySystem.cs | 2 + 20 files changed, 485 insertions(+), 39 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs index dcf727d34..b242b7a2c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs @@ -77,5 +77,14 @@ internal static unsafe ref PointCollider GetPointCollider(this in BlobAssetRefer return ref UnsafeUtility.AsRef(pointCollider); } } + + internal static unsafe ref FlipperCollider GetFlipperCollider(this in BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var flipperCollider = (FlipperCollider*) cPtr; + return ref UnsafeUtility.AsRef(flipperCollider); + } + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index a4e51c66d..cfe3493c9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -37,9 +37,8 @@ public PhysicsCycle(Allocator a) } internal void Simulate(float dTime, ref PhysicsState state, in NativeOctree octree, - ref BlobAssetReference colliders, ref NativeList balls, - ref InsideOfs insideOfs, - ref NativeQueue.ParallelWriter events) + ref BlobAssetReference colliders, ref NativeList balls, ref NativeHashMap flipperStates, + ref InsideOfs insideOfs, ref NativeQueue.ParallelWriter events, uint timeMs) { var staticCounts = PhysicsConstants.StaticCnts; @@ -67,7 +66,7 @@ internal void Simulate(float dTime, ref PhysicsState state, in NativeOctree // static narrow phase PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, in _overlappingColliders, ref colliders, - ref insideOfs, ref _contacts); + ref insideOfs, ref _contacts, ref flipperStates); // write ball back balls[i] = ball; @@ -85,13 +84,19 @@ internal void Simulate(float dTime, ref PhysicsState state, in NativeOctree balls[i] = ball; } + foreach (var i in flipperStates.GetKeyArray(Allocator.Temp)) { + var flipperState = flipperStates[i]; + FlipperDisplacementPhysics.UpdateDisplacement(flipperState.ItemId, ref flipperState.Movement, ref flipperState.Tricks, in flipperState.Static, hitTime, ref events); + flipperStates[i] = flipperState; + } + for (var i = 0; i < balls.Length; i++) { var ball = balls[i]; // todo dynamic collision // static collision - PhysicsStaticCollision.Collide(hitTime, ref ball, ref colliders, ref state.Random, ref events); + PhysicsStaticCollision.Collide(hitTime, ref ball, ref colliders, ref flipperStates, ref state.Random, ref events, timeMs); balls[i] = ball; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index c4b93dcff..7b60568d6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -22,6 +22,7 @@ using Unity.Collections; using Unity.Entities; using Unity.Jobs; +using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Common; using VisualPinball.Unity.VisualPinball.Unity.Game; @@ -34,12 +35,17 @@ public class PhysicsEngine : MonoBehaviour { [NonSerialized] private NativeArray _physicsState; [NonSerialized] private NativeOctree _octree; - [NonSerialized] private NativeList _balls; - [NonSerialized] private NativeQueue _eventQueue; [NonSerialized] private BlobAssetReference _colliders; + [NonSerialized] private NativeQueue _eventQueue; [NonSerialized] private InsideOfs _insideOfs; + + [NonSerialized] private NativeList _balls; [NonSerialized] private readonly Dictionary _ballLookup = new(); + [NonSerialized] private NativeHashMap _flipperStates; + + [NonSerialized] public Dictionary FlipperLookup = new(); + private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); private void Start() @@ -47,20 +53,26 @@ private void Start() var player = GetComponent(); // init state - _physicsState = new NativeArray(1, Allocator.Persistent); - _physicsState[0] = new PhysicsState(NowUsec, GetComponent()); + var physicsState = new PhysicsState(NowUsec, GetComponent()); _insideOfs = new InsideOfs(Allocator.Persistent); // create static octree var sw = Stopwatch.StartNew(); var colliderItems = GetComponentsInChildren(); - Debug.Log($"Found {colliderItems.Length} collidable items."); var managedColliders = new List(); foreach (var colliderItem in colliderItems) { colliderItem.GetColliders(player, managedColliders, 0); } + // data: flippers + var flippers = GetComponentsInChildren(); + _flipperStates = new NativeHashMap(flippers.Length, Allocator.Persistent); + foreach (var flipper in flippers) { + var flipperState = flipper.NewState(); + _flipperStates[flipperState.ItemId] = flipperState; + } + // allocate colliders _colliders = AllocateColliders(managedColliders); @@ -87,6 +99,8 @@ private void Start() } _eventQueue = new NativeQueue(Allocator.Persistent); + _physicsState = new NativeArray(1, Allocator.Persistent); + _physicsState[0] = physicsState; } private static BlobAssetReference AllocateColliders(IEnumerable managedColliders) @@ -106,20 +120,26 @@ private void Update() PhysicsState = _physicsState, Octree = _octree, Colliders = _colliders, - Balls = _balls, InsideOfs = _insideOfs, Events = events, + Balls = _balls, + FlipperStates = _flipperStates, }; updatePhysics.Run(); _balls = updatePhysics.Balls; _physicsState = updatePhysics.PhysicsState; + _flipperStates = updatePhysics.FlipperStates; foreach (var ballData in _balls) { var ball = _ballLookup[ballData.Id]; BallMovementPhysics.Move(ballData, _ballLookup[ball.Id].transform); } + foreach (var itemId in _flipperStates.GetKeyArray(Allocator.Temp)) { + var flipper = FlipperLookup[itemId]; + flipper.transform.localRotation = quaternion.Euler(0, _flipperStates[itemId].Movement.Angle, 0); + } } private void OnDestroy() @@ -155,10 +175,12 @@ internal struct UpdatePhysicsJob : IJob public NativeArray PhysicsState; public NativeOctree Octree; public BlobAssetReference Colliders; - public NativeList Balls; public InsideOfs InsideOfs; public NativeQueue.ParallelWriter Events; + public NativeList Balls; + public NativeHashMap FlipperStates; + public void Execute() { var n = 0; @@ -173,12 +195,19 @@ public void Execute() // update velocities - always on integral physics frame boundary (spinner, gate, flipper, plunger, ball) for (var i = 0; i < Balls.Length; i++) { var ball = Balls[i]; - BallVelocityPhysics.UpdateVelocities(state.Gravity, ref ball); + BallVelocityPhysics.UpdateVelocities(ref ball, state.Gravity); Balls[i] = ball; } - + + foreach (var i in FlipperStates.GetKeyArray(Allocator.Temp)) { + var flipper = FlipperStates[i]; + FlipperVelocityPhysics.UpdateVelocities(ref flipper); + FlipperStates[i] = flipper; + + } + // primary physics loop - cycle.Simulate(physicsDiffTime, ref state, in Octree, ref Colliders, ref Balls, ref InsideOfs, ref Events); + cycle.Simulate(physicsDiffTime, ref state, in Octree, ref Colliders, ref Balls, ref FlipperStates, ref InsideOfs, ref Events, timeMsec); state.CurPhysicsFrameTime = state.NextPhysicsFrameTime; state.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index d84b6df00..23284bc57 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -14,12 +14,14 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; using Unity.Mathematics; using VisualPinball.Engine.Common; +using Random = Unity.Mathematics.Random; namespace VisualPinball.Unity { - public struct PhysicsState + public struct PhysicsState : IDisposable { public readonly float3 Gravity; public readonly ulong StartTimeUsec; @@ -36,5 +38,9 @@ public PhysicsState(ulong startTimeUsec, Player player) : this() Random = new Random((uint)UnityEngine.Random.Range(1, 100000)); Gravity = player.Gravity; } + + public void Dispose() + { + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index f645d0814..aaab360a1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -28,7 +28,9 @@ internal static class PhysicsStaticCollision { private static readonly ProfilerMarker PerfMarker = new("PhysicsStaticCollision"); - internal static void Collide(float hitTime, ref BallData ball, ref BlobAssetReference colliders, ref Random random, ref NativeQueue.ParallelWriter events) + internal static void Collide(float hitTime, ref BallData ball, ref BlobAssetReference colliders, + ref NativeHashMap flipperStates, + ref Random random, ref NativeQueue.ParallelWriter events, uint timeMs) { // find balls with hit objects and minimum time @@ -38,7 +40,7 @@ internal static void Collide(float hitTime, ref BallData ball, ref BlobAssetRefe PerfMarker.Begin(); - Collide(ref ball, ref colliders, ref random, ref events); + Collide(ref ball, ref colliders, ref flipperStates, ref random, ref events, timeMs); // remove trial hit object pointer ball.CollisionEvent.ClearCollider(); @@ -46,7 +48,8 @@ internal static void Collide(float hitTime, ref BallData ball, ref BlobAssetRefe PerfMarker.End(); } - private static void Collide(ref BallData ball, ref BlobAssetReference colliders, ref Random random, ref NativeQueue.ParallelWriter events) + private static void Collide(ref BallData ball, ref BlobAssetReference colliders, ref NativeHashMap flipperStates, + ref Random random, ref NativeQueue.ParallelWriter events, uint timeMs) { switch (colliders.GetType(ball.CollisionEvent.ColliderId)) { case ColliderType.Plane: @@ -64,6 +67,13 @@ private static void Collide(ref BallData ball, ref BlobAssetReference overlappingColliders, ref BlobAssetReference colliders, ref InsideOfs insideOfs, - ref NativeList contacts) + ref NativeList contacts, ref NativeHashMap flipperStates + ) { PerfMarker.Begin(); @@ -42,7 +43,7 @@ internal static void FindNextCollision( for (var i = 0; i < overlappingColliders.Length; i++) { var newCollEvent = new CollisionEventData(); var colliderRef = new ColliderRef(overlappingColliders[i], ref colliders); - var newTime = colliderRef.HitTest(ref ball, ref newCollEvent, ref insideOfs, ref contacts); + var newTime = colliderRef.HitTest(ref ball, ref newCollEvent, ref insideOfs, ref contacts, ref colliders, ref flipperStates); SaveCollisions(ref ball, ref newCollEvent, ref contacts, colliderRef.Id, newTime); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs index 874f67f5f..cd5113c9a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs @@ -1,4 +1,20 @@ -using Unity.Collections; +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Collections; using Unity.Entities; namespace VisualPinball.Unity @@ -15,7 +31,7 @@ internal ColliderRef(int id, ref BlobAssetReference colliders) } internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref InsideOfs insideOfs, - ref NativeList contacts) + ref NativeList contacts, ref BlobAssetReference colliders, ref NativeHashMap flipperStates) { var hitTime = -1f; switch (_colliders.GetType(Id)) { @@ -34,6 +50,14 @@ internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref case ColliderType.Point: hitTime = _colliders.GetPointCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); break; + case ColliderType.Flipper: + var collider = colliders.Value.Colliders[collEvent.ColliderId].Value; + var flipperState = flipperStates[collider.ItemId]; + hitTime = _colliders.GetFlipperCollider(Id).HitTest( + ref collEvent, ref insideOfs, ref flipperState.Hit, + in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, in ball, collEvent.HitTime + ); + break; } return hitTime; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs index 7de413e4b..81102e1ac 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs @@ -41,9 +41,11 @@ public class DefaultPhysicsEngine : IPhysicsEngine private int _nextBallIdToNotifyDebugUI; private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; + private TableComponent _tableComponent; public void Init(TableComponent tableComponent, BallManager ballManager) { + _tableComponent = tableComponent; _ballManager = ballManager; _entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; // _flipperDataQuery = _entityManager.CreateEntityQuery( @@ -98,22 +100,21 @@ public void BallManualRoll(in Entity entity, in float3 targetWorldPosition) public void FlipperRotateToEnd(in int itemId) { - // fixme job - // var mData = _entityManager.GetComponentData(entity); - // mData.EnableRotateEvent = 1; - // mData.StartRotateToEndTime = _visualPinballSimulationSystemGroup.TimeMsec; - // mData.AngleAtRotateToEnd = mData.Angle; - // _entityManager.SetComponentData(entity, mData); - // _entityManager.SetComponentData(entity, new SolenoidStateData { Value = true }); + var physicsEngine = _tableComponent.GetComponent(); + var mData = _entityManager.GetComponentData(entity); + mData.EnableRotateEvent = 1; + mData.StartRotateToEndTime = _visualPinballSimulationSystemGroup.TimeMsec; + mData.AngleAtRotateToEnd = mData.Angle; + _entityManager.SetComponentData(entity, mData); + _entityManager.SetComponentData(entity, new SolenoidStateData { Value = true }); } public void FlipperRotateToStart(in int itemId) { - // fixme job - // var mData = _entityManager.GetComponentData(entity); - // mData.EnableRotateEvent = -1; - // _entityManager.SetComponentData(entity, mData); - // _entityManager.SetComponentData(entity, new SolenoidStateData { Value = false }); + var mData = _entityManager.GetComponentData(entity); + mData.EnableRotateEvent = -1; + _entityManager.SetComponentData(entity, mData); + _entityManager.SetComponentData(entity, new SolenoidStateData { Value = false }); } public DebugFlipperState[] FlipperGetDebugStates() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs index 969908747..d3425e83f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs @@ -16,6 +16,7 @@ using Unity.Entities; using Unity.Mathematics; +using VisualPinballUnity; namespace VisualPinball.Unity { @@ -149,6 +150,8 @@ the angular velocity used here is not the angular velocity that the ball has (wh */ } + public void UpdateVelocities(float3 gravity) => BallVelocityPhysics.UpdateVelocities(ref this, gravity); + public override string ToString() { return $"Ball{Id} ({Position.x}/{Position.y})"; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs index 67c554c0b..65c46d5e6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs @@ -27,7 +27,7 @@ internal static class BallVelocityPhysics { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallVelocityPhysics"); - public static void UpdateVelocities(float3 gravity, ref BallData ball) + public static void UpdateVelocities(ref BallData ball, float3 gravity) { PerfMarker.Begin(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs index 0fbc0edf7..91d7190fa 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs @@ -16,6 +16,7 @@ // ReSharper disable InconsistentNaming +using System.Collections.Generic; using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Flipper; @@ -24,7 +25,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Collision/Flipper Collider")] [HelpURL("https://docs.visualpinball.org/creators-guide/manual/mechanisms/flippers.html")] - public class FlipperColliderComponent : ColliderComponent + public class FlipperColliderComponent : ColliderComponent, ICollidableComponent { #region Data @@ -123,7 +124,7 @@ public class FlipperColliderComponent : ColliderComponent /// If set, apply Live Catch (nFozzy/RothBauerW) /// - #endregion + [Tooltip("The nFozzy's LiveCatch Physics")] public bool useFlipperLiveCatch = false; @@ -157,8 +158,14 @@ public class FlipperColliderComponent : ColliderComponent new FlipperApi(gameObject, player); + void ICollidableComponent.GetColliders(Player player, List colliders, float margin) + { + InstantiateColliderApi(player).CreateColliders(colliders, margin); + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index f1a7f6f31..75b56e8e9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -476,6 +476,7 @@ public List GetEnclosingPolygon(float margin = 0.0F, float stepSize = 5 private void Awake() { _originalRotateZ = _startAngle; + GetComponentInParent().FlipperLookup.Add(gameObject.GetInstanceID(), gameObject); } private void Start() @@ -487,6 +488,32 @@ private void Start() #region DOTS Data + internal FlipperState NewState() + { + var colliderComponent = gameObject.GetComponent(); + // collision + if (colliderComponent) { + + // vpx physics + var d = GetMaterialData(colliderComponent); + return new FlipperState( + gameObject.GetInstanceID(), + d, + GetMovementData(d), + GetVelocityData(d), + GetHitData(), + GetFlipperTricksData(colliderComponent, d), + new SolenoidStateData { Value = false } + ); + + // flipper correction (nFozzy) + // if (colliderComponent.FlipperCorrection) { + // SetupFlipperCorrection(entity, dstManager, player, colliderComponent); + // } + } + return default; + } + internal FlipperTricksData GetFlipperTricksData(FlipperColliderComponent colliderComponent, FlipperStaticData staticData) { return new FlipperTricksData diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs new file mode 100644 index 000000000..0e66092a9 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs @@ -0,0 +1,89 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Collections; +using Unity.Mathematics; +using VisualPinball.Engine.Game; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class FlipperDisplacementPhysics + { + internal static void UpdateDisplacement(int itemId, ref FlipperMovementData state, ref FlipperTricksData tricks, in FlipperStaticData data, + float dTime, ref NativeQueue.ParallelWriter events) + { + //var dTime = _simulateCycleSystemGroup.HitTime; + var currentTime = 0;// todo SystemAPI.Time.ElapsedTime; + + state.Angle += state.AngleSpeed * dTime; // move flipper angle + + var angleMin = math.min(data.AngleStart, tricks.AngleEnd); + var angleMax = math.max(data.AngleStart, tricks.AngleEnd); + + if (state.Angle > angleMax) { + state.Angle = angleMax; + } + + if (state.Angle < angleMin) { + state.Angle = angleMin; + } + + if (math.abs(state.AngleSpeed) < 0.0005f) { + // avoids "jumping balls" when two or more balls held on flipper (and more other balls are in play) //!! make dependent on physics update rate + return; + } + + var handleEvent = false; + + // ReSharper disable once CompareOfFloatsByEqualityOperator + if (state.Angle == tricks.AngleEnd) { + tricks.FlipperAngleEndTime = currentTime; + } + + if (state.Angle >= angleMax) { + // hit stop? + if (state.AngleSpeed > 0) { + handleEvent = true; + } + + } else if (state.Angle <= angleMin) { + if (state.AngleSpeed < 0) { + handleEvent = true; + } + } + + if (handleEvent) { + var angleSpeed = math.abs(math.degrees(state.AngleSpeed)); + state.AngularMomentum *= -0.3f; // make configurable? + state.AngleSpeed = state.AngularMomentum / data.Inertia; + + if (state.EnableRotateEvent > 0) { + + // send EOS event + events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, angleSpeed)); + + } else if (state.EnableRotateEvent < 0) { + + // send BOS event + events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, angleSpeed)); + } + + state.EnableRotateEvent = 0; + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs.meta new file mode 100644 index 000000000..6896bb020 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 971a7144094d47e39f1182c608bff07a +timeCreated: 1696163536 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs index 184b41fa6..082ca0df6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs @@ -14,19 +14,21 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; using Unity.Collections; using Unity.Entities; using Unity.Mathematics; using Unity.Profiling; -using UnityEngine; using VisualPinball.Engine.Game; using VisualPinball.Unity; using VisualPinball.Unity.VisualPinball.Unity.Game; +using Object = UnityEngine.Object; namespace VisualPinballUnity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] + [Obsolete("Use FlipperDisplacementPhysics instead.")] internal partial class FlipperDisplacementSystem : SystemBaseStub { private Player _player; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs new file mode 100644 index 000000000..37b92ee5b --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs @@ -0,0 +1,42 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal struct FlipperState + { + internal int ItemId; + internal FlipperStaticData Static; + internal FlipperMovementData Movement; + internal FlipperVelocityData Velocity; + internal FlipperHitData Hit; + internal FlipperTricksData Tricks; + internal SolenoidStateData Solenoid; + + public FlipperState(int itemId, FlipperStaticData @static, FlipperMovementData movement, + FlipperVelocityData velocity, FlipperHitData hit, FlipperTricksData tricks, + SolenoidStateData solenoid) + { + ItemId = itemId; + Static = @static; + Movement = movement; + Velocity = velocity; + Hit = hit; + Tricks = tricks; + Solenoid = solenoid; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs.meta new file mode 100644 index 000000000..9fcaf194a --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 761c2c59a9e948a7b674703f9bc04d79 +timeCreated: 1696161233 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs new file mode 100644 index 000000000..e4ba38d41 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs @@ -0,0 +1,180 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable CompareOfFloatsByEqualityOperator + +using Unity.Mathematics; +using VisualPinball.Engine.Common; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class FlipperVelocityPhysics + { + internal static void UpdateVelocities(ref FlipperState state) + { + ref var mState = ref state.Movement; + ref var vState = ref state.Velocity; + ref var tricks = ref state.Tricks; + ref var solenoid = ref state.Solenoid; + ref var data = ref state.Static; + + var angleMin = math.min(data.AngleStart, tricks.AngleEnd); + var angleMax = math.max(data.AngleStart, tricks.AngleEnd); + var minIsStart = angleMin == data.AngleStart; // Usually true for the right Flipper + + var desiredTorque = data.Strength; + if (!solenoid.Value) + { + // True solState = button pressed, false = released + desiredTorque *= -data.ReturnRatio; + } + + if (tricks.UseFlipperTricksPhysics) { + // check if solenoid was just activated or deactivated + if (solenoid.Value != tricks.lastSolState) + { + // check if solenoid was just activated or deactivated for Flippertricks + // Flippertricks case 1 and 2 are always before case 3, 4 and 5. + if (solenoid.Value) + { + // Flippertricks, case 2 (OnButtonActivate) + tricks.TorqueDamping = tricks.OriginalTorqueDamping; + tricks.TorqueDampingAngle = tricks.OriginalTorqueDampingAngle; + tricks.ElasticityMultiplier = 1f; + } + else + { + // Flippertricks, case 1 (OnButtonDeactivate) + tricks.TorqueDamping = tricks.OriginalTorqueDamping * tricks.EOSReturn / data.ReturnRatio; + tricks.TorqueDampingAngle = tricks.OriginalTorqueDampingAngle; + } + } + } + + // hold coil is weaker + float eosAngle = math.radians(tricks.TorqueDampingAngle); + if (math.abs(mState.Angle - tricks.AngleEnd) < eosAngle) { + // fade in/out damping, depending on angle to end + var lerp = math.pow(math.abs(mState.Angle - tricks.AngleEnd) / eosAngle, 4); + if (tricks.UseFlipperTricksPhysics) + desiredTorque *= lerp + tricks.TorqueDamping * (1 - lerp); + else + desiredTorque *= lerp + tricks.TorqueDamping * (1 - lerp); + } + + if (!vState.Direction) { + desiredTorque = -desiredTorque; + } + + var torqueRampUpSpeed = tricks.RampUpSpeed; + if (torqueRampUpSpeed <= 0) { + // set very high for instant coil response + torqueRampUpSpeed = 1e6f; + + } else { + torqueRampUpSpeed = math.min(data.Strength / torqueRampUpSpeed, 1e6f); + } + + // update current torque linearly towards desired torque + // (simple model for coil hysteresis) + if (desiredTorque >= vState.CurrentTorque) { + vState.CurrentTorque = math.min(vState.CurrentTorque + torqueRampUpSpeed * (float)PhysicsConstants.PhysFactor, desiredTorque); + + } else { + vState.CurrentTorque = math.max(vState.CurrentTorque - torqueRampUpSpeed * (float)PhysicsConstants.PhysFactor, desiredTorque); + } + + // resolve contacts with stoppers + var torque = vState.CurrentTorque; + vState.IsInContact = false; + if (math.abs(mState.AngleSpeed) <= 1e-2) { + + if (mState.Angle >= angleMax - 1e-2 && torque > 0) { + mState.Angle = angleMax; + vState.IsInContact = true; + vState.ContactTorque = torque; + mState.AngularMomentum = 0f; + torque = 0f; + + } else if (mState.Angle <= angleMin + 1e-2 && torque < 0) { + mState.Angle = angleMin; + vState.IsInContact = true; + vState.ContactTorque = torque; + mState.AngularMomentum = 0f; + torque = 0f; + } + } + + mState.AngularMomentum += (float)PhysicsConstants.PhysFactor * torque; + mState.AngleSpeed = mState.AngularMomentum / data.Inertia; + vState.AngularAcceleration = torque / data.Inertia; + + if (tricks.UseFlipperTricksPhysics) + { + // Flippertricks, case 3 (OnFlipperDown) and 4 (OnFlipperUpResting) + if (!tricks.WasInContact && vState.IsInContact) + { + // the flipper stopped due to being at max or min angle. + // so check if at start angle + if (((mState.Angle == angleMin) && (minIsStart)) || + ((mState.Angle == angleMax) && (!minIsStart))) + { + // is at start angle + // FlipperTricks case 3: OnFlipperDown + if (minIsStart) + tricks.AngleEnd = tricks.OriginalAngleEnd + tricks.Overshoot; + else + tricks.AngleEnd = tricks.OriginalAngleEnd - tricks.Overshoot; + + tricks.RampUpSpeed = tricks.SOSRampUp; + tricks.ElasticityMultiplier = tricks.SOSEM; + + //data.ft = 3f; + } + else + { + // is at end angle + // FlipperTricks case 4: OnFlipperUpResting + tricks.AngleEnd = tricks.OriginalAngleEnd; // This causes the flipper to instantly flip back to normal end angle (like in the original Flippertricks implementation) + tricks.RampUpSpeed = tricks.EOSRampup; + tricks.TorqueDamping = tricks.EOSTNew; + tricks.TorqueDampingAngle = tricks.EOSANew; + + //data.ft = 4f; + } + } + + // Flippertricks, case 5 (OnEnterinbetween) (and pressed) + if ((tricks.WasInContact) && (!vState.IsInContact) && solenoid.Value) + { + // Flippertricks Case 5 + tricks.RampUpSpeed = tricks.OriginalRampUpSpeed; + tricks.TorqueDamping = tricks.OriginalTorqueDamping; + tricks.TorqueDampingAngle = tricks.OriginalTorqueDampingAngle; + tricks.ElasticityMultiplier = 1f; + + //data.ft = 5f; + } + + tricks.WasInContact = vState.IsInContact; + + // check if solenoid was just activated or deactivated + tricks.lastSolState = solenoid.Value; + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs.meta new file mode 100644 index 000000000..7ea3399a3 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d014647421cc4e3aacc873b43e34b68b +timeCreated: 1696189650 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs index 250d999e8..20bb5de74 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs @@ -16,6 +16,7 @@ // ReSharper disable CompareOfFloatsByEqualityOperator +using System; using Unity.Entities; using Unity.Mathematics; using Unity.Profiling; @@ -27,6 +28,7 @@ namespace VisualPinballUnity { [AlwaysSynchronizeSystem] [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] + [Obsolete("Use FlipperVelocityPhysics instead.")] internal partial class FlipperVelocitySystem : SystemBaseStub { private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("FlipperVelocitySystem"); From e75b7877c0ba9e0961ec437468e221f000c136dd Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 2 Oct 2023 21:40:00 +0200 Subject: [PATCH 053/159] jobs: Okay, the flipper is moving, but the data is still disgusting. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 7 ++++- .../Physics/Engine/DefaultPhysicsEngine.cs | 29 ++++++++++++------- .../VPT/Flipper/FlipperComponent.cs | 1 + 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 7b60568d6..a864df799 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -46,6 +46,8 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] public Dictionary FlipperLookup = new(); + [NonSerialized] internal Queue, PhysicsState>> Actions = new(); + private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); private void Start() @@ -125,7 +127,10 @@ private void Update() Balls = _balls, FlipperStates = _flipperStates, }; - + + foreach (var action in Actions) { + action(_flipperStates, _physicsState[0]); + } updatePhysics.Run(); _balls = updatePhysics.Balls; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs index 81102e1ac..cb53da8ce 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs @@ -100,21 +100,30 @@ public void BallManualRoll(in Entity entity, in float3 targetWorldPosition) public void FlipperRotateToEnd(in int itemId) { + var id = itemId; var physicsEngine = _tableComponent.GetComponent(); - var mData = _entityManager.GetComponentData(entity); - mData.EnableRotateEvent = 1; - mData.StartRotateToEndTime = _visualPinballSimulationSystemGroup.TimeMsec; - mData.AngleAtRotateToEnd = mData.Angle; - _entityManager.SetComponentData(entity, mData); - _entityManager.SetComponentData(entity, new SolenoidStateData { Value = true }); + physicsEngine.Actions.Enqueue((flipperStates, state) => { + var timeMsec = (uint)((state.CurPhysicsFrameTime - state.StartTimeUsec) / 1000); + var flipperState = flipperStates[id]; + flipperState.Movement.EnableRotateEvent = 1; + flipperState.Movement.StartRotateToEndTime = timeMsec; + flipperState.Movement.AngleAtRotateToEnd = flipperState.Movement.Angle; + flipperState.Solenoid.Value = true; + flipperStates[id] = flipperState; + }); } public void FlipperRotateToStart(in int itemId) { - var mData = _entityManager.GetComponentData(entity); - mData.EnableRotateEvent = -1; - _entityManager.SetComponentData(entity, mData); - _entityManager.SetComponentData(entity, new SolenoidStateData { Value = false }); + var id = itemId; + var physicsEngine = _tableComponent.GetComponent(); + physicsEngine.Actions.Enqueue((flipperStates, state) => { + var timeMsec = (uint)((state.CurPhysicsFrameTime - state.StartTimeUsec) / 1000); + var flipperState = flipperStates[id]; + flipperState.Movement.EnableRotateEvent = -1; + flipperState.Solenoid.Value = false; + flipperStates[id] = flipperState; + }); } public DebugFlipperState[] FlipperGetDebugStates() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index 75b56e8e9..1fc9193de 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -476,6 +476,7 @@ public List GetEnclosingPolygon(float margin = 0.0F, float stepSize = 5 private void Awake() { _originalRotateZ = _startAngle; + GetComponentInParent().RegisterFlipper(this); GetComponentInParent().FlipperLookup.Add(gameObject.GetInstanceID(), gameObject); } From 11a66bc1eb7231728b7d3e362a64adafed6c4bb5 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 2 Oct 2023 22:25:03 +0200 Subject: [PATCH 054/159] jobs: Pack physics state into a single struct once in the job. --- .../VisualPinball.Unity/Game/PhysicsBall.cs | 2 +- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 47 ++++---- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 56 +++++----- .../VisualPinball.Unity/Game/PhysicsEnv.cs | 46 ++++++++ .../Game/PhysicsEnv.cs.meta | 3 + .../VisualPinball.Unity/Game/PhysicsState.cs | 104 ++++++++++-------- .../Game/PhysicsState.cs.meta | 4 +- .../Game/PhysicsStaticCollision.cs | 32 +++--- .../Game/PhysicsStaticNarrowPhase.cs | 12 +- .../Physics/Collider/ColliderRef.cs | 16 +-- .../VPT/Flipper/FlipperCollider.cs | 6 +- .../VPT/Flipper/FlipperState.cs | 7 +- 12 files changed, 194 insertions(+), 141 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs index fcdcc9763..55ba24ae5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs @@ -20,7 +20,7 @@ using Unity.Mathematics; using UnityEngine; -namespace VisualPinball.Unity.VisualPinball.Unity.Game +namespace VisualPinball.Unity { public class PhysicsBall : MonoBehaviour { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index cfe3493c9..ae861e035 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -15,9 +15,7 @@ // along with this program. If not, see . using System; -using NativeTrees; using Unity.Collections; -using Unity.Entities; using VisualPinball.Engine.Common; using VisualPinballUnity; @@ -36,11 +34,8 @@ public PhysicsCycle(Allocator a) _overlappingColliders = new NativeList(a); } - internal void Simulate(float dTime, ref PhysicsState state, in NativeOctree octree, - ref BlobAssetReference colliders, ref NativeList balls, ref NativeHashMap flipperStates, - ref InsideOfs insideOfs, ref NativeQueue.ParallelWriter events, uint timeMs) + internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) { - var staticCounts = PhysicsConstants.StaticCnts; while (dTime > 0) { @@ -54,22 +49,21 @@ internal void Simulate(float dTime, ref PhysicsState state, in NativeOctree // todo dynamic broad phase - for (var i = 0; i < balls.Length; i++) { - var ball = balls[i]; + for (var i = 0; i < state.Balls.Length; i++) { + var ball = state.Balls[i]; if (ball.IsFrozen) { continue; } // static broad phase - PhysicsStaticBroadPhase.FindOverlaps(in octree, in ball, ref _overlappingColliders); + PhysicsStaticBroadPhase.FindOverlaps(in state.Octree, in ball, ref _overlappingColliders); // static narrow phase - PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, in _overlappingColliders, ref colliders, - ref insideOfs, ref _contacts, ref flipperStates); + PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, in _overlappingColliders, ref _contacts, ref state); // write ball back - balls[i] = ball; + state.Balls[i] = ball; // todo dynamic narrow phase @@ -78,35 +72,34 @@ internal void Simulate(float dTime, ref PhysicsState state, in NativeOctree } // displacement - for (var i = 0; i < balls.Length; i++) { // todo loop through all "movers", not just balls - var ball = balls[i]; + for (var i = 0; i < state.Balls.Length; i++) { // todo loop through all "movers", not just balls + var ball = state.Balls[i]; BallDisplacementPhysics.UpdateDisplacements(ref ball, hitTime); // use static method instead of member - balls[i] = ball; + state.Balls[i] = ball; } - - foreach (var i in flipperStates.GetKeyArray(Allocator.Temp)) { - var flipperState = flipperStates[i]; - FlipperDisplacementPhysics.UpdateDisplacement(flipperState.ItemId, ref flipperState.Movement, ref flipperState.Tricks, in flipperState.Static, hitTime, ref events); - flipperStates[i] = flipperState; + foreach (var i in state.FlipperStates.GetKeyArray(Allocator.Temp)) { + var flipperState = state.FlipperStates[i]; + FlipperDisplacementPhysics.UpdateDisplacement(flipperState.ItemId, ref flipperState.Movement, ref flipperState.Tricks, in flipperState.Static, hitTime, ref state.EventQueue); + state.FlipperStates[i] = flipperState; } - for (var i = 0; i < balls.Length; i++) { - var ball = balls[i]; + for (var i = 0; i < state.Balls.Length; i++) { + var ball = state.Balls[i]; // todo dynamic collision // static collision - PhysicsStaticCollision.Collide(hitTime, ref ball, ref colliders, ref flipperStates, ref state.Random, ref events, timeMs); + PhysicsStaticCollision.Collide(hitTime, ref ball, timeMs, ref state); - balls[i] = ball; + state.Balls[i] = ball; } // handle contacts - var b = balls[0]; + var b = state.Balls[0]; foreach (var contact in _contacts) { - BallCollider.HandleStaticContact(ref b, in contact.CollEvent, colliders.GetFriction(contact.CollEvent.ColliderId), hitTime, state.Gravity); + BallCollider.HandleStaticContact(ref b, in contact.CollEvent, state.Colliders.GetFriction(contact.CollEvent.ColliderId), hitTime, state.Env.Gravity); } - balls[0] = b; + state.Balls[0] = b; // clear contacts _contacts.Clear(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index a864df799..714d700f3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -24,8 +24,8 @@ using Unity.Jobs; using Unity.Mathematics; using UnityEngine; +using UnityEngine.Serialization; using VisualPinball.Engine.Common; -using VisualPinball.Unity.VisualPinball.Unity.Game; using VisualPinballUnity; using Debug = UnityEngine.Debug; @@ -33,20 +33,18 @@ namespace VisualPinball.Unity { public class PhysicsEngine : MonoBehaviour { - [NonSerialized] private NativeArray _physicsState; + [NonSerialized] private NativeArray _physicsEnv; [NonSerialized] private NativeOctree _octree; [NonSerialized] private BlobAssetReference _colliders; [NonSerialized] private NativeQueue _eventQueue; [NonSerialized] private InsideOfs _insideOfs; - [NonSerialized] private NativeList _balls; - [NonSerialized] private readonly Dictionary _ballLookup = new(); - [NonSerialized] private NativeHashMap _flipperStates; + [NonSerialized] private readonly Dictionary _ballLookup = new(); [NonSerialized] public Dictionary FlipperLookup = new(); - [NonSerialized] internal Queue, PhysicsState>> Actions = new(); + [NonSerialized] internal Queue, PhysicsEnv>> Actions = new(); private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); @@ -55,7 +53,7 @@ private void Start() var player = GetComponent(); // init state - var physicsState = new PhysicsState(NowUsec, GetComponent()); + var physicsState = new PhysicsEnv(NowUsec, GetComponent()); _insideOfs = new InsideOfs(Allocator.Persistent); // create static octree @@ -101,8 +99,8 @@ private void Start() } _eventQueue = new NativeQueue(Allocator.Persistent); - _physicsState = new NativeArray(1, Allocator.Persistent); - _physicsState[0] = physicsState; + _physicsEnv = new NativeArray(1, Allocator.Persistent); + _physicsEnv[0] = physicsState; } private static BlobAssetReference AllocateColliders(IEnumerable managedColliders) @@ -119,7 +117,7 @@ private void Update() var events = _eventQueue.AsParallelWriter(); var updatePhysics = new UpdatePhysicsJob { InitialTimeUsec = NowUsec, - PhysicsState = _physicsState, + PhysicsEnv = _physicsEnv, Octree = _octree, Colliders = _colliders, InsideOfs = _insideOfs, @@ -129,12 +127,12 @@ private void Update() }; foreach (var action in Actions) { - action(_flipperStates, _physicsState[0]); + action(_flipperStates, _physicsEnv[0]); } updatePhysics.Run(); _balls = updatePhysics.Balls; - _physicsState = updatePhysics.PhysicsState; + _physicsEnv = updatePhysics.PhysicsEnv; _flipperStates = updatePhysics.FlipperStates; foreach (var ballData in _balls) { @@ -149,7 +147,7 @@ private void Update() private void OnDestroy() { - _physicsState.Dispose(); + _physicsEnv.Dispose(); _eventQueue.Dispose(); _balls.Dispose(); _colliders.Dispose(); @@ -177,7 +175,7 @@ internal struct UpdatePhysicsJob : IJob { [ReadOnly] public ulong InitialTimeUsec; - public NativeArray PhysicsState; + [FormerlySerializedAs("PhysicsState")] public NativeArray PhysicsEnv; public NativeOctree Octree; public BlobAssetReference Colliders; public InsideOfs InsideOfs; @@ -188,19 +186,22 @@ internal struct UpdatePhysicsJob : IJob public void Execute() { - var n = 0; - var state = PhysicsState[0]; + var env = PhysicsEnv[0]; + var state = new PhysicsState(ref env, ref Octree, ref Colliders, ref Events, ref InsideOfs, ref Balls, ref FlipperStates); var cycle = new PhysicsCycle(Allocator.Temp); - - while (state.CurPhysicsFrameTime < InitialTimeUsec) // loop here until current (real) time matches the physics (simulated) time + var n = 0; + + while (env.CurPhysicsFrameTime < InitialTimeUsec) // loop here until current (real) time matches the physics (simulated) time { - var timeMsec = (uint)((state.CurPhysicsFrameTime - state.StartTimeUsec) / 1000); - var physicsDiffTime = (float)((state.NextPhysicsFrameTime - state.CurPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); + var timeMsec = (uint)((env.CurPhysicsFrameTime - env.StartTimeUsec) / 1000); + var physicsDiffTime = (float)((env.NextPhysicsFrameTime - env.CurPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); + + #region Update Velocities // update velocities - always on integral physics frame boundary (spinner, gate, flipper, plunger, ball) for (var i = 0; i < Balls.Length; i++) { var ball = Balls[i]; - BallVelocityPhysics.UpdateVelocities(ref ball, state.Gravity); + BallVelocityPhysics.UpdateVelocities(ref ball, env.Gravity); Balls[i] = ball; } @@ -208,19 +209,20 @@ public void Execute() var flipper = FlipperStates[i]; FlipperVelocityPhysics.UpdateVelocities(ref flipper); FlipperStates[i] = flipper; - } + #endregion + // primary physics loop - cycle.Simulate(physicsDiffTime, ref state, in Octree, ref Colliders, ref Balls, ref FlipperStates, ref InsideOfs, ref Events, timeMsec); - - state.CurPhysicsFrameTime = state.NextPhysicsFrameTime; - state.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; + cycle.Simulate(ref state, physicsDiffTime, timeMsec); + + env.CurPhysicsFrameTime = env.NextPhysicsFrameTime; + env.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; n++; } - PhysicsState[0] = state; + PhysicsEnv[0] = env; cycle.Dispose(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs new file mode 100644 index 000000000..13348a4db --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs @@ -0,0 +1,46 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using Unity.Mathematics; +using VisualPinball.Engine.Common; +using Random = Unity.Mathematics.Random; + +namespace VisualPinball.Unity +{ + public struct PhysicsEnv : IDisposable + { + public readonly float3 Gravity; + public readonly ulong StartTimeUsec; + public ulong CurPhysicsFrameTime; + public ulong NextPhysicsFrameTime; + + public Random Random; + + public PhysicsEnv(ulong startTimeUsec, Player player) : this() + { + StartTimeUsec = startTimeUsec; + CurPhysicsFrameTime = StartTimeUsec; + NextPhysicsFrameTime = StartTimeUsec + PhysicsConstants.PhysicsStepTime; + Random = new Random((uint)UnityEngine.Random.Range(1, 100000)); + Gravity = player.Gravity; + } + + public void Dispose() + { + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs.meta new file mode 100644 index 000000000..565fdfea9 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b915f496c6ce491ba0ed3143007a1fe8 +timeCreated: 1678661883 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 23284bc57..fd0b7ee41 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -1,46 +1,58 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using Unity.Mathematics; -using VisualPinball.Engine.Common; -using Random = Unity.Mathematics.Random; - -namespace VisualPinball.Unity -{ - public struct PhysicsState : IDisposable - { - public readonly float3 Gravity; - public readonly ulong StartTimeUsec; - public ulong CurPhysicsFrameTime; - public ulong NextPhysicsFrameTime; - - public Random Random; - - public PhysicsState(ulong startTimeUsec, Player player) : this() - { - StartTimeUsec = startTimeUsec; - CurPhysicsFrameTime = StartTimeUsec; - NextPhysicsFrameTime = StartTimeUsec + PhysicsConstants.PhysicsStepTime; - Random = new Random((uint)UnityEngine.Random.Range(1, 100000)); - Gravity = player.Gravity; - } - - public void Dispose() - { - } - } -} +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using NativeTrees; +using Unity.Collections; +using Unity.Entities; + +namespace VisualPinball.Unity +{ + internal struct PhysicsState + { + internal PhysicsEnv Env; + internal NativeOctree Octree; + internal BlobAssetReference Colliders; + internal NativeQueue.ParallelWriter EventQueue; + internal InsideOfs InsideOfs; + internal NativeList Balls; + internal NativeHashMap FlipperStates; + + public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAssetReference colliders, + ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeList balls, + ref NativeHashMap flipperStates) + { + Env = env; + Octree = octree; + Colliders = colliders; + EventQueue = eventQueue; + InsideOfs = insideOfs; + Balls = balls; + FlipperStates = flipperStates; + } + + internal FlipperState GetFlipperState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return FlipperStates[collider.ItemId]; + } + + internal void SetFlipperState(int colliderId, FlipperState state) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + FlipperStates[collider.ItemId] = state; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs.meta index 3db946934..075d404dc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs.meta @@ -1,3 +1,3 @@ fileFormatVersion: 2 -guid: b915f496c6ce491ba0ed3143007a1fe8 -timeCreated: 1678661883 \ No newline at end of file +guid: 5f6509a9a6e74f81a4c439f5c2f4a2d2 +timeCreated: 1696276234 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index aaab360a1..4790b758f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -16,9 +16,6 @@ // ReSharper disable ConvertIfStatementToSwitchStatement -using Unity.Collections; -using Unity.Entities; -using Unity.Mathematics; using Unity.Profiling; using VisualPinball.Unity; @@ -28,9 +25,7 @@ internal static class PhysicsStaticCollision { private static readonly ProfilerMarker PerfMarker = new("PhysicsStaticCollision"); - internal static void Collide(float hitTime, ref BallData ball, ref BlobAssetReference colliders, - ref NativeHashMap flipperStates, - ref Random random, ref NativeQueue.ParallelWriter events, uint timeMs) + internal static void Collide(float hitTime, ref BallData ball, uint timeMs, ref PhysicsState state) { // find balls with hit objects and minimum time @@ -40,7 +35,7 @@ internal static void Collide(float hitTime, ref BallData ball, ref BlobAssetRefe PerfMarker.Begin(); - Collide(ref ball, ref colliders, ref flipperStates, ref random, ref events, timeMs); + Collide(ref ball, timeMs, ref state); // remove trial hit object pointer ball.CollisionEvent.ClearCollider(); @@ -48,31 +43,30 @@ internal static void Collide(float hitTime, ref BallData ball, ref BlobAssetRefe PerfMarker.End(); } - private static void Collide(ref BallData ball, ref BlobAssetReference colliders, ref NativeHashMap flipperStates, - ref Random random, ref NativeQueue.ParallelWriter events, uint timeMs) + private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState state) { - switch (colliders.GetType(ball.CollisionEvent.ColliderId)) { + switch (state.Colliders.GetType(ball.CollisionEvent.ColliderId)) { case ColliderType.Plane: - colliders.GetPlaneCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, in ball.CollisionEvent, ref random); + state.Colliders.GetPlaneCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Line: - colliders.GetLineCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref events, ball.Id, in ball.CollisionEvent, ref random); + state.Colliders.GetLineCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Triangle: - colliders.GetTriangleCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref events, ball.Id, in ball.CollisionEvent, ref random); + state.Colliders.GetTriangleCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Line3D: - colliders.GetLine3DCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref events, ball.Id, in ball.CollisionEvent, ref random); + state.Colliders.GetLine3DCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Point: - colliders.GetPointCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref events, ball.Id, in ball.CollisionEvent, ref random); + state.Colliders.GetPointCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Flipper: - var collider = colliders.Value.Colliders[ball.CollisionEvent.ColliderId].Value; - var flipperState = flipperStates[collider.ItemId]; - colliders.GetFlipperCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, - ref events, in ball.Id, in flipperState.Tricks, in flipperState.Static, + var flipperState = state.GetFlipperState(ball.CollisionEvent.ColliderId); + state.Colliders.GetFlipperCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, + ref state.EventQueue, in ball.Id, in flipperState.Tricks, in flipperState.Static, in flipperState.Velocity, in flipperState.Hit, timeMs); + state.SetFlipperState(ball.CollisionEvent.ColliderId, flipperState); break; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index a93479d65..8035d1644 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -17,7 +17,6 @@ // ReSharper disable ForCanBeConvertedToForeach using Unity.Collections; -using Unity.Entities; using Unity.Profiling; namespace VisualPinball.Unity @@ -30,10 +29,9 @@ internal static void FindNextCollision( float hitTime, ref BallData ball, in NativeList overlappingColliders, - ref BlobAssetReference colliders, - ref InsideOfs insideOfs, - ref NativeList contacts, ref NativeHashMap flipperStates - ) + ref NativeList contacts, + ref PhysicsState state + ) { PerfMarker.Begin(); @@ -42,8 +40,8 @@ ref NativeList contacts, ref NativeHashMap colliders) Id = id; } - internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref InsideOfs insideOfs, - ref NativeList contacts, ref BlobAssetReference colliders, ref NativeHashMap flipperStates) + internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref NativeList contacts, ref PhysicsState state) { var hitTime = -1f; switch (_colliders.GetType(Id)) { @@ -39,10 +38,10 @@ internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref hitTime = _colliders.GetPlaneCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); break; case ColliderType.Line: - hitTime = _colliders.GetLineCollider(Id).HitTest(ref collEvent, ref insideOfs, ref ball, ball.CollisionEvent.HitTime); + hitTime = _colliders.GetLineCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, ref ball, ball.CollisionEvent.HitTime); break; case ColliderType.Triangle: - hitTime = _colliders.GetTriangleCollider(Id).HitTest(ref collEvent, in insideOfs, in ball, ball.CollisionEvent.HitTime); + hitTime = _colliders.GetTriangleCollider(Id).HitTest(ref collEvent, in state.InsideOfs, in ball, ball.CollisionEvent.HitTime); break; case ColliderType.Line3D: hitTime = _colliders.GetLine3DCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); @@ -51,12 +50,13 @@ internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref hitTime = _colliders.GetPointCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); break; case ColliderType.Flipper: - var collider = colliders.Value.Colliders[collEvent.ColliderId].Value; - var flipperState = flipperStates[collider.ItemId]; + var flipperState = state.GetFlipperState(collEvent.ColliderId); hitTime = _colliders.GetFlipperCollider(Id).HitTest( - ref collEvent, ref insideOfs, ref flipperState.Hit, - in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, in ball, collEvent.HitTime + ref collEvent, ref state.InsideOfs, ref flipperState.Hit, + in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, + in ball, collEvent.HitTime ); + state.SetFlipperState(collEvent.ColliderId, flipperState); break; } return hitTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs index 43c434157..c7bfb7577 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs @@ -152,9 +152,9 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray Date: Tue, 3 Oct 2023 00:45:16 +0200 Subject: [PATCH 055/159] jobs: Pass whole state to input actions. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 22 +++++++++++-------- .../Physics/Engine/DefaultPhysicsEngine.cs | 16 +++++++------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 714d700f3..e84425878 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -42,9 +42,10 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeHashMap _flipperStates; [NonSerialized] private readonly Dictionary _ballLookup = new(); - [NonSerialized] public Dictionary FlipperLookup = new(); + [NonSerialized] public readonly Dictionary FlipperLookup = new(); - [NonSerialized] internal Queue, PhysicsEnv>> Actions = new(); + [NonSerialized] internal readonly Queue InputActions = new(); + internal delegate void InputAction(ref PhysicsState state); private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); @@ -53,7 +54,7 @@ private void Start() var player = GetComponent(); // init state - var physicsState = new PhysicsEnv(NowUsec, GetComponent()); + var env = new PhysicsEnv(NowUsec, GetComponent()); _insideOfs = new InsideOfs(Allocator.Persistent); // create static octree @@ -80,7 +81,7 @@ private void Start() var elapsedMs = sw.Elapsed.TotalMilliseconds; var playfieldBounds = GetComponentInChildren().Bounds; _octree = new NativeOctree(playfieldBounds, 32, 10, Allocator.Persistent); - + sw.Restart(); var populateJob = new PopulatePhysicsJob { Colliders = _colliders, @@ -89,7 +90,7 @@ private void Start() populateJob.Run(); _octree = populateJob.Octree; Debug.Log($"Octree of {_colliders.Value.Colliders.Length} constructed (colliders: {elapsedMs}ms, tree: {sw.Elapsed.TotalMilliseconds}ms)."); - + // get balls var balls = GetComponentsInChildren(); _balls = new NativeList(balls.Length, Allocator.Persistent); @@ -97,10 +98,10 @@ private void Start() _balls.Add(ball.Data); _ballLookup[ball.Id] = ball; } - + _eventQueue = new NativeQueue(Allocator.Persistent); _physicsEnv = new NativeArray(1, Allocator.Persistent); - _physicsEnv[0] = physicsState; + _physicsEnv[0] = env; } private static BlobAssetReference AllocateColliders(IEnumerable managedColliders) @@ -126,8 +127,11 @@ private void Update() FlipperStates = _flipperStates, }; - foreach (var action in Actions) { - action(_flipperStates, _physicsEnv[0]); + var env = _physicsEnv[0]; + var state = new PhysicsState(ref env, ref _octree, ref _colliders, ref events, ref _insideOfs, ref _balls, ref _flipperStates); + + foreach (var action in InputActions) { + action(ref state); } updatePhysics.Run(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs index cb53da8ce..8dab7283c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs @@ -102,14 +102,14 @@ public void FlipperRotateToEnd(in int itemId) { var id = itemId; var physicsEngine = _tableComponent.GetComponent(); - physicsEngine.Actions.Enqueue((flipperStates, state) => { - var timeMsec = (uint)((state.CurPhysicsFrameTime - state.StartTimeUsec) / 1000); - var flipperState = flipperStates[id]; + physicsEngine.InputActions.Enqueue((ref PhysicsState state) => { + var timeMsec = (uint)((state.Env.CurPhysicsFrameTime - state.Env.StartTimeUsec) / 1000); + var flipperState = state.FlipperStates[id]; flipperState.Movement.EnableRotateEvent = 1; flipperState.Movement.StartRotateToEndTime = timeMsec; flipperState.Movement.AngleAtRotateToEnd = flipperState.Movement.Angle; flipperState.Solenoid.Value = true; - flipperStates[id] = flipperState; + state.FlipperStates[id] = flipperState; }); } @@ -117,12 +117,12 @@ public void FlipperRotateToStart(in int itemId) { var id = itemId; var physicsEngine = _tableComponent.GetComponent(); - physicsEngine.Actions.Enqueue((flipperStates, state) => { - var timeMsec = (uint)((state.CurPhysicsFrameTime - state.StartTimeUsec) / 1000); - var flipperState = flipperStates[id]; + physicsEngine.InputActions.Enqueue((ref PhysicsState state) => { + var timeMsec = (uint)((state.Env.CurPhysicsFrameTime - state.Env.StartTimeUsec) / 1000); + var flipperState = state.FlipperStates[id]; flipperState.Movement.EnableRotateEvent = -1; flipperState.Solenoid.Value = false; - flipperStates[id] = flipperState; + state.FlipperStates[id] = flipperState; }); } From 8a997087bd640095329edaf9b4008c2461e02c45 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 4 Oct 2023 00:08:53 +0200 Subject: [PATCH 056/159] jobs: Modify flipper state directly instead of a copy. --- .../VisualPinball.Unity/Collections.meta | 3 + .../Collections/AssemblyInfo.cs | 3 + .../Collections/AssemblyInfo.cs.meta | 3 + .../Collections/CollectionExtensions.cs | 86 +++++++++++++++++++ .../Collections/CollectionExtensions.cs.meta | 3 + .../Collections/CollectionReference.asmref | 3 + .../CollectionReference.asmref.meta | 3 + .../VisualPinball.Unity/Game/PhysicsEngine.cs | 6 +- .../VisualPinball.Unity/Game/PhysicsState.cs | 19 ++-- .../Game/PhysicsStaticCollision.cs | 1 - .../Physics/Collider/ColliderRef.cs | 1 - .../VPT/Flipper/FlipperState.cs | 5 -- 12 files changed, 117 insertions(+), 19 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections/AssemblyInfo.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections/AssemblyInfo.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionReference.asmref create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionReference.asmref.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections.meta b/VisualPinball.Unity/VisualPinball.Unity/Collections.meta new file mode 100644 index 000000000..40b7a7b10 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a8226ee24ab34f1ea5940bfb5736c9d5 +timeCreated: 1696369879 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/AssemblyInfo.cs b/VisualPinball.Unity/VisualPinball.Unity/Collections/AssemblyInfo.cs new file mode 100644 index 000000000..f1df0a3fe --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("VisualPinball.Unity.Collections")] diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/AssemblyInfo.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Collections/AssemblyInfo.cs.meta new file mode 100644 index 000000000..bae708483 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/AssemblyInfo.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b49ec6e82c524d6f920855969a015f8f +timeCreated: 1696368718 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs new file mode 100644 index 000000000..f1567514c --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs @@ -0,0 +1,86 @@ +// MIT License +// +// Copyright (c) 2022 Timothy Raines +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using System; +using System.Collections.Generic; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; + +namespace VisualPinball.Unity.Collections +{ + /// + /// Part of Tertle's excellent Core extensions. + /// + /// See https://gitlab.com/tertle/com.bovinelabs.core + /// + public static unsafe class CollectionExtensions + { + /// + /// Returns a reference to the value associated with the specified key. Does not copy the value. + /// + /// The hashmap to retrieve the reference to the value from + /// The key of the hashmap pointing to the value + /// Type of the hashmap's key + /// Type of the hashmap's value + /// Reference to the value + /// Source + public static ref TValue GetValueByRef(this NativeParallelHashMap map, TKey key) + where TKey : unmanaged, IEquatable + where TValue : unmanaged + { + return ref map.m_HashMapData.m_Buffer->GetValueByRef(key); + } + + /// Source + private static ref TValue GetValueByRef(this ref UnsafeParallelHashMapData data, TKey key) + where TKey : struct, IEquatable + where TValue : struct + { +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (data.allocatedIndexLength <= 0) + { + throw new KeyNotFoundException(); + } +#endif + + // First find the slot based on the hash + var buckets = (int*)data.buckets; + var bucket = key.GetHashCode() & data.bucketCapacityMask; + var entryIdx = buckets[bucket]; + + var nextPtrs = (int*)data.next; + while (!UnsafeUtility.ReadArrayElement(data.keys, entryIdx).Equals(key)) + { + entryIdx = nextPtrs[entryIdx]; +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if ((entryIdx < 0) || (entryIdx >= data.keyCapacity)) + { + throw new KeyNotFoundException(); + } +#endif + } + + // Read the value + return ref UnsafeUtility.ArrayElementAsRef(data.values, entryIdx); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs.meta new file mode 100644 index 000000000..8d7b91bbf --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2d9514da4f354444b3350df327f761d8 +timeCreated: 1696368479 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionReference.asmref b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionReference.asmref new file mode 100644 index 000000000..369c8b2c6 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionReference.asmref @@ -0,0 +1,3 @@ +{ + "reference": "GUID:e0cd26848372d4e5c891c569017e11f1" +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionReference.asmref.meta b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionReference.asmref.meta new file mode 100644 index 000000000..4c2539af2 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionReference.asmref.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a8ab32aaa18d4966b7a5974294f069c2 +timeCreated: 1696369605 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index e84425878..4adf297ec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -39,7 +39,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeQueue _eventQueue; [NonSerialized] private InsideOfs _insideOfs; [NonSerialized] private NativeList _balls; - [NonSerialized] private NativeHashMap _flipperStates; + [NonSerialized] private NativeParallelHashMap _flipperStates; [NonSerialized] private readonly Dictionary _ballLookup = new(); [NonSerialized] public readonly Dictionary FlipperLookup = new(); @@ -68,7 +68,7 @@ private void Start() // data: flippers var flippers = GetComponentsInChildren(); - _flipperStates = new NativeHashMap(flippers.Length, Allocator.Persistent); + _flipperStates = new NativeParallelHashMap(flippers.Length, Allocator.Persistent); foreach (var flipper in flippers) { var flipperState = flipper.NewState(); _flipperStates[flipperState.ItemId] = flipperState; @@ -186,7 +186,7 @@ internal struct UpdatePhysicsJob : IJob public NativeQueue.ParallelWriter Events; public NativeList Balls; - public NativeHashMap FlipperStates; + public NativeParallelHashMap FlipperStates; public void Execute() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index fd0b7ee41..bac9f0c29 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -17,6 +17,7 @@ using NativeTrees; using Unity.Collections; using Unity.Entities; +using VisualPinball.Unity.Collections; namespace VisualPinball.Unity { @@ -28,11 +29,11 @@ internal struct PhysicsState internal NativeQueue.ParallelWriter EventQueue; internal InsideOfs InsideOfs; internal NativeList Balls; - internal NativeHashMap FlipperStates; + internal NativeParallelHashMap FlipperStates; public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAssetReference colliders, ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeList balls, - ref NativeHashMap flipperStates) + ref NativeParallelHashMap flipperStates) { Env = env; Octree = octree; @@ -43,16 +44,16 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs FlipperStates = flipperStates; } - internal FlipperState GetFlipperState(int colliderId) + internal unsafe ref FlipperState GetFlipperState(int colliderId) { var collider = Colliders.Value.Colliders[colliderId].Value; - return FlipperStates[collider.ItemId]; + return ref FlipperStates.GetValueByRef(collider.ItemId); } - internal void SetFlipperState(int colliderId, FlipperState state) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - FlipperStates[collider.ItemId] = state; - } + // internal void SetFlipperState(int colliderId, FlipperState state) + // { + // var collider = Colliders.Value.Colliders[colliderId].Value; + // FlipperStates[collider.ItemId] = state; + // } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 4790b758f..80f06734c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -66,7 +66,6 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta state.Colliders.GetFlipperCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, ref state.EventQueue, in ball.Id, in flipperState.Tricks, in flipperState.Static, in flipperState.Velocity, in flipperState.Hit, timeMs); - state.SetFlipperState(ball.CollisionEvent.ColliderId, flipperState); break; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs index 8173b18bb..c95e017f4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs @@ -56,7 +56,6 @@ internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, in ball, collEvent.HitTime ); - state.SetFlipperState(collEvent.ColliderId, flipperState); break; } return hitTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs index 5d8561ca3..9ce7b80fb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs @@ -16,11 +16,6 @@ namespace VisualPinball.Unity { - internal interface IMovableStruct - { - void UpdateVelocities(); - } - internal struct FlipperState { internal readonly int ItemId; From fbebd991d91f44bc2602cb330934dd5461cfb73a Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 4 Oct 2023 00:26:58 +0200 Subject: [PATCH 057/159] jobs: Use ball references instead of copies. --- .../Collections/CollectionExtensions.cs | 9 ++ .../Game/PhysicsColliderExtensions.cs | 2 +- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 87 ++++++++++--------- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 42 +++++---- .../VisualPinball.Unity/Game/PhysicsState.cs | 14 +-- .../Game/PhysicsStaticCollision.cs | 2 +- .../Physics/Collider/ColliderRef.cs | 2 +- 7 files changed, 85 insertions(+), 73 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs index f1567514c..c065c79f7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs @@ -82,5 +82,14 @@ private static ref TValue GetValueByRef(this ref UnsafeParallelHas // Read the value return ref UnsafeUtility.ArrayElementAsRef(data.values, entryIdx); } + + #region Own stuff + + public static ref T GetElementAsRef(this NativeList list, int index) where T : unmanaged + { + return ref UnsafeUtility.ArrayElementAsRef(list.GetUnsafePtr(), index); + } + + #endregion } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs index b242b7a2c..54b18b21d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs @@ -19,7 +19,7 @@ namespace VisualPinball.Unity { - public static partial class PhysicsColliderExtensions + public static class PhysicsColliderExtensions { internal static int GetId(this BlobAssetReference colliders, int index) => colliders.Value.Colliders[index].Value.Id; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index ae861e035..a6705f5dc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -17,6 +17,7 @@ using System; using Unity.Collections; using VisualPinball.Engine.Common; +using VisualPinball.Unity.Collections; using VisualPinballUnity; namespace VisualPinball.Unity @@ -48,58 +49,62 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) _contacts.Clear(); // todo dynamic broad phase + using (var enumerator = state.Balls.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var ball = ref enumerator.Current.Value; - for (var i = 0; i < state.Balls.Length; i++) { - var ball = state.Balls[i]; - - if (ball.IsFrozen) { - continue; + if (ball.IsFrozen) { + continue; + } + + // static broad phase + PhysicsStaticBroadPhase.FindOverlaps(in state.Octree, in ball, ref _overlappingColliders); + + // static narrow phase + PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, in _overlappingColliders, ref _contacts, ref state); + + // todo dynamic narrow phase + + // apply static time + ApplyStaticTime(ref hitTime, ref staticCounts, in ball); } - - // static broad phase - PhysicsStaticBroadPhase.FindOverlaps(in state.Octree, in ball, ref _overlappingColliders); - - // static narrow phase - PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, in _overlappingColliders, ref _contacts, ref state); - - // write ball back - state.Balls[i] = ball; - - // todo dynamic narrow phase - - // apply static time - ApplyStaticTime(ref hitTime, ref staticCounts, in ball); } + #region Displacement + // displacement - for (var i = 0; i < state.Balls.Length; i++) { // todo loop through all "movers", not just balls - var ball = state.Balls[i]; - BallDisplacementPhysics.UpdateDisplacements(ref ball, hitTime); // use static method instead of member - state.Balls[i] = ball; + using (var enumerator = state.Balls.GetEnumerator()) { + while (enumerator.MoveNext()) { + BallDisplacementPhysics.UpdateDisplacements(ref enumerator.Current.Value, hitTime); // use static method instead of member + } } - foreach (var i in state.FlipperStates.GetKeyArray(Allocator.Temp)) { - var flipperState = state.FlipperStates[i]; - FlipperDisplacementPhysics.UpdateDisplacement(flipperState.ItemId, ref flipperState.Movement, ref flipperState.Tricks, in flipperState.Static, hitTime, ref state.EventQueue); - state.FlipperStates[i] = flipperState; + + using (var enumerator = state.FlipperStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var flipperState = ref enumerator.Current.Value; + FlipperDisplacementPhysics.UpdateDisplacement(flipperState.ItemId, ref flipperState.Movement, ref flipperState.Tricks, in flipperState.Static, hitTime, ref state.EventQueue); + } } - for (var i = 0; i < state.Balls.Length; i++) { - var ball = state.Balls[i]; - - // todo dynamic collision - - // static collision - PhysicsStaticCollision.Collide(hitTime, ref ball, timeMs, ref state); - - state.Balls[i] = ball; + #endregion + + using (var enumerator = state.Balls.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var ball = ref enumerator.Current.Value; + + // todo dynamic collision + + // static collision + PhysicsStaticCollision.Collide(hitTime, ref ball, timeMs, ref state); + } } - + // handle contacts - var b = state.Balls[0]; - foreach (var contact in _contacts) { - BallCollider.HandleStaticContact(ref b, in contact.CollEvent, state.Colliders.GetFriction(contact.CollEvent.ColliderId), hitTime, state.Env.Gravity); + for (var i = 0; i < _contacts.Length; i++) { + ref var contact = ref _contacts.GetElementAsRef(i); + ref var ball = ref state.Balls.GetValueByRef(contact.BallId); + BallCollider.HandleStaticContact(ref ball, in contact.CollEvent, state.Colliders.GetFriction(contact.CollEvent.ColliderId), hitTime, state.Env.Gravity); } - state.Balls[0] = b; // clear contacts _contacts.Clear(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 4adf297ec..45475c189 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -38,7 +38,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private BlobAssetReference _colliders; [NonSerialized] private NativeQueue _eventQueue; [NonSerialized] private InsideOfs _insideOfs; - [NonSerialized] private NativeList _balls; + [NonSerialized] private NativeParallelHashMap _balls; [NonSerialized] private NativeParallelHashMap _flipperStates; [NonSerialized] private readonly Dictionary _ballLookup = new(); @@ -93,9 +93,9 @@ private void Start() // get balls var balls = GetComponentsInChildren(); - _balls = new NativeList(balls.Length, Allocator.Persistent); + _balls = new NativeParallelHashMap(balls.Length, Allocator.Persistent); foreach (var ball in balls) { - _balls.Add(ball.Data); + _balls.Add(ball.Id, ball.Data); _ballLookup[ball.Id] = ball; } @@ -139,13 +139,17 @@ private void Update() _physicsEnv = updatePhysics.PhysicsEnv; _flipperStates = updatePhysics.FlipperStates; - foreach (var ballData in _balls) { - var ball = _ballLookup[ballData.Id]; - BallMovementPhysics.Move(ballData, _ballLookup[ball.Id].transform); + using (var enumerator = state.Balls.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var ball = ref enumerator.Current.Value; + BallMovementPhysics.Move(ball, _ballLookup[ball.Id].transform); + } } - foreach (var itemId in _flipperStates.GetKeyArray(Allocator.Temp)) { - var flipper = FlipperLookup[itemId]; - flipper.transform.localRotation = quaternion.Euler(0, _flipperStates[itemId].Movement.Angle, 0); + using (var enumerator = _flipperStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + var flipper = FlipperLookup[enumerator.Current.Key]; + flipper.transform.localRotation = quaternion.Euler(0, _flipperStates[enumerator.Current.Key].Movement.Angle, 0); + } } } @@ -185,7 +189,7 @@ internal struct UpdatePhysicsJob : IJob public InsideOfs InsideOfs; public NativeQueue.ParallelWriter Events; - public NativeList Balls; + public NativeParallelHashMap Balls; public NativeParallelHashMap FlipperStates; public void Execute() @@ -203,16 +207,16 @@ public void Execute() #region Update Velocities // update velocities - always on integral physics frame boundary (spinner, gate, flipper, plunger, ball) - for (var i = 0; i < Balls.Length; i++) { - var ball = Balls[i]; - BallVelocityPhysics.UpdateVelocities(ref ball, env.Gravity); - Balls[i] = ball; - } - foreach (var i in FlipperStates.GetKeyArray(Allocator.Temp)) { - var flipper = FlipperStates[i]; - FlipperVelocityPhysics.UpdateVelocities(ref flipper); - FlipperStates[i] = flipper; + using (var enumerator = state.Balls.GetEnumerator()) { + while (enumerator.MoveNext()) { + BallVelocityPhysics.UpdateVelocities(ref enumerator.Current.Value, env.Gravity); + } + } + using (var enumerator = FlipperStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + FlipperVelocityPhysics.UpdateVelocities(ref enumerator.Current.Value); + } } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index bac9f0c29..2fc400211 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -28,11 +28,11 @@ internal struct PhysicsState internal BlobAssetReference Colliders; internal NativeQueue.ParallelWriter EventQueue; internal InsideOfs InsideOfs; - internal NativeList Balls; + internal NativeParallelHashMap Balls; internal NativeParallelHashMap FlipperStates; public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAssetReference colliders, - ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeList balls, + ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeParallelHashMap balls, ref NativeParallelHashMap flipperStates) { Env = env; @@ -44,16 +44,10 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs FlipperStates = flipperStates; } - internal unsafe ref FlipperState GetFlipperState(int colliderId) + internal ref FlipperState GetFlipperState(in CollisionEventData collisionEvent) { - var collider = Colliders.Value.Colliders[colliderId].Value; + var collider = Colliders.Value.Colliders[collisionEvent.ColliderId].Value; return ref FlipperStates.GetValueByRef(collider.ItemId); } - - // internal void SetFlipperState(int colliderId, FlipperState state) - // { - // var collider = Colliders.Value.Colliders[colliderId].Value; - // FlipperStates[collider.ItemId] = state; - // } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 80f06734c..cd3e29a77 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -62,7 +62,7 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta state.Colliders.GetPointCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Flipper: - var flipperState = state.GetFlipperState(ball.CollisionEvent.ColliderId); + ref var flipperState = ref state.GetFlipperState(in ball.CollisionEvent); state.Colliders.GetFlipperCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, ref state.EventQueue, in ball.Id, in flipperState.Tricks, in flipperState.Static, in flipperState.Velocity, in flipperState.Hit, timeMs); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs index c95e017f4..aab30bf44 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs @@ -50,7 +50,7 @@ internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref hitTime = _colliders.GetPointCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); break; case ColliderType.Flipper: - var flipperState = state.GetFlipperState(collEvent.ColliderId); + var flipperState = state.GetFlipperState(in collEvent); hitTime = _colliders.GetFlipperCollider(Id).HitTest( ref collEvent, ref state.InsideOfs, ref flipperState.Hit, in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, From 130cf046c7133a3dc17f2a7d78fbc068cec60097 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 4 Oct 2023 00:29:20 +0200 Subject: [PATCH 058/159] jobs: Add profile markers. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 22 +++++++++++++++++++ .../VisualPinball.Unity/Game/PhysicsEngine.cs | 2 +- .../Game/PhysicsStaticBroadPhase.cs | 5 ----- .../Game/PhysicsStaticCollision.cs | 7 ------ .../Game/PhysicsStaticNarrowPhase.cs | 7 ------ .../VPT/Ball/BallDisplacementPhysics.cs | 7 ------ .../VPT/Ball/BallMovementPhysics.cs | 7 ------ .../VPT/Ball/BallVelocityPhysics.cs | 7 ------ 8 files changed, 23 insertions(+), 41 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index a6705f5dc..74a9e1eec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -16,6 +16,7 @@ using System; using Unity.Collections; +using Unity.Profiling; using VisualPinball.Engine.Common; using VisualPinball.Unity.Collections; using VisualPinballUnity; @@ -29,6 +30,13 @@ public struct PhysicsCycle : IDisposable [NativeDisableParallelForRestriction] private NativeList _overlappingColliders; + private static readonly ProfilerMarker PerfMarker = new("PhysicsCycle"); + private static readonly ProfilerMarker PerfMarkerBroadPhase = new("BroadPhase"); + private static readonly ProfilerMarker PerfMarkerNarrowPhase = new("NarrowPhase"); + private static readonly ProfilerMarker PerfMarkerDisplacement = new("Displacement"); + private static readonly ProfilerMarker PerfMarkerCollision = new("Collision"); + private static readonly ProfilerMarker PerfMarkerContacts = new("Contacts"); + public PhysicsCycle(Allocator a) { _contacts = new NativeList(a); @@ -37,6 +45,7 @@ public PhysicsCycle(Allocator a) internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) { + PerfMarker.Begin(); var staticCounts = PhysicsConstants.StaticCnts; while (dTime > 0) { @@ -49,6 +58,7 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) _contacts.Clear(); // todo dynamic broad phase + using (var enumerator = state.Balls.GetEnumerator()) { while (enumerator.MoveNext()) { ref var ball = ref enumerator.Current.Value; @@ -58,10 +68,14 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) } // static broad phase + PerfMarkerBroadPhase.Begin(); PhysicsStaticBroadPhase.FindOverlaps(in state.Octree, in ball, ref _overlappingColliders); + PerfMarkerBroadPhase.End(); // static narrow phase + PerfMarkerNarrowPhase.Begin(); PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, in _overlappingColliders, ref _contacts, ref state); + PerfMarkerNarrowPhase.End(); // todo dynamic narrow phase @@ -71,6 +85,7 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) } #region Displacement + PerfMarkerDisplacement.Begin(); // displacement using (var enumerator = state.Balls.GetEnumerator()) { @@ -86,8 +101,11 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) } } + PerfMarkerDisplacement.End(); #endregion + // collision + PerfMarkerCollision.Begin(); using (var enumerator = state.Balls.GetEnumerator()) { while (enumerator.MoveNext()) { ref var ball = ref enumerator.Current.Value; @@ -98,13 +116,16 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) PhysicsStaticCollision.Collide(hitTime, ref ball, timeMs, ref state); } } + PerfMarkerCollision.End(); // handle contacts + PerfMarkerContacts.Begin(); for (var i = 0; i < _contacts.Length; i++) { ref var contact = ref _contacts.GetElementAsRef(i); ref var ball = ref state.Balls.GetValueByRef(contact.BallId); BallCollider.HandleStaticContact(ref ball, in contact.CollEvent, state.Colliders.GetFriction(contact.CollEvent.ColliderId), hitTime, state.Env.Gravity); } + PerfMarkerContacts.End(); // clear contacts _contacts.Clear(); @@ -113,6 +134,7 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) dTime -= hitTime; } + PerfMarker.End(); } private static void ApplyStaticTime(ref float hitTime, ref float staticCounts, in BallData ball) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 45475c189..498e7e545 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -48,7 +48,7 @@ public class PhysicsEngine : MonoBehaviour internal delegate void InputAction(ref PhysicsState state); private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); - + private void Start() { var player = GetComponent(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs index 191837fcd..ba744f572 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs @@ -16,20 +16,15 @@ using NativeTrees; using Unity.Collections; -using Unity.Profiling; namespace VisualPinball.Unity { public static class PhysicsStaticBroadPhase { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("StaticBroadPhase"); - internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeList overlappingColliders) { - PerfMarker.Begin(); overlappingColliders.Clear(); octree.RangeAABB(ball.Aabb, overlappingColliders); - PerfMarker.End(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index cd3e29a77..515915f49 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -16,15 +16,12 @@ // ReSharper disable ConvertIfStatementToSwitchStatement -using Unity.Profiling; using VisualPinball.Unity; namespace VisualPinballUnity { internal static class PhysicsStaticCollision { - private static readonly ProfilerMarker PerfMarker = new("PhysicsStaticCollision"); - internal static void Collide(float hitTime, ref BallData ball, uint timeMs, ref PhysicsState state) { @@ -33,14 +30,10 @@ internal static void Collide(float hitTime, ref BallData ball, uint timeMs, ref return; } - PerfMarker.Begin(); - Collide(ref ball, timeMs, ref state); // remove trial hit object pointer ball.CollisionEvent.ClearCollider(); - - PerfMarker.End(); } private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState state) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index 8035d1644..7060e64fa 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -17,14 +17,11 @@ // ReSharper disable ForCanBeConvertedToForeach using Unity.Collections; -using Unity.Profiling; namespace VisualPinball.Unity { public static class PhysicsStaticNarrowPhase { - private static readonly ProfilerMarker PerfMarker = new("PhysicsStaticNarrowPhase"); - internal static void FindNextCollision( float hitTime, ref BallData ball, @@ -33,8 +30,6 @@ internal static void FindNextCollision( ref PhysicsState state ) { - PerfMarker.Begin(); - // init contacts and event ball.CollisionEvent.ClearCollider(hitTime); // search upto current hit time @@ -49,8 +44,6 @@ ref PhysicsState state if (ball.CollisionEvent.HitTime < 0) { ball.CollisionEvent.ClearCollider(); } - - PerfMarker.End(); } private static float HitTest(ref BallData ball, in Collider collider, ref NativeList contacts) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs index 621f82b58..a239e0351 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using Unity.Mathematics; -using Unity.Profiling; using UnityEngine; using VisualPinball.Unity; @@ -23,12 +22,8 @@ namespace VisualPinballUnity { internal static class BallDisplacementPhysics { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallDisplacementPhysics"); - internal static void UpdateDisplacements(ref BallData ball, float dTime) { - PerfMarker.Begin(); - ball.Position += ball.Velocity * dTime; var inertia = ball.Inertia; @@ -50,8 +45,6 @@ internal static void UpdateDisplacements(ref BallData ball, float dTime) VPOrthonormalize(ref ball.BallOrientation); VPOrthonormalize(ref ball.BallOrientationForUnity); - - PerfMarker.End(); } private static void VPOrthonormalize(ref float3x3 orientation) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs index 77ec75199..aeea4e2cc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs @@ -24,8 +24,6 @@ namespace VisualPinballUnity internal static class BallMovementPhysics { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallMovementSystem"); - // protected override void OnStartRunning() // { // var root = Object.FindObjectOfType(); @@ -41,8 +39,6 @@ internal static class BallMovementPhysics public static void Move(BallData ball, Transform ballTransform) { - PerfMarker.Begin(); - // calculate/adapt height of ball var zHeight = !ball.IsFrozen ? ball.Position.z : ball.Position.z - ball.Radius; ballTransform.localPosition = Physics.TranslateToWorld(ball.Position.x, ball.Position.y, zHeight); @@ -66,9 +62,6 @@ public static void Move(BallData ball, Transform ballTransform) q = FlipZAxis(q); ballTransform.localRotation = q.RotateToWorld(); - - PerfMarker.End(); - static Quaternion FlipZAxis(Quaternion q) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs index 65c46d5e6..3e077ad8b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs @@ -17,7 +17,6 @@ // ReSharper disable CompareOfFloatsByEqualityOperator using Unity.Mathematics; -using Unity.Profiling; using VisualPinball.Engine.Common; using VisualPinball.Unity; @@ -25,12 +24,8 @@ namespace VisualPinballUnity { internal static class BallVelocityPhysics { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallVelocityPhysics"); - public static void UpdateVelocities(ref BallData ball, float3 gravity) { - PerfMarker.Begin(); - if (ball.IsFrozen) { return; } @@ -45,8 +40,6 @@ public static void UpdateVelocities(ref BallData ball, float3 gravity) } else { ball.Velocity += (float)PhysicsConstants.PhysFactor * gravity; } - - PerfMarker.End(); } } } From 54c058ccd36e289fcd31e68c25223ff37c14f3a0 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 4 Oct 2023 23:40:15 +0200 Subject: [PATCH 059/159] jobs: Add bumpers. --- .../Collections/CollectionExtensions.cs | 2 +- .../Game/InitPlayerSystem.cs | 30 ---- .../Game/InitPlayerSystem.cs.meta | 3 - .../Game/PhysicsColliderExtensions.cs | 11 +- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 93 +++++++++-- .../VisualPinball.Unity/Game/PhysicsState.cs | 17 +- .../Game/PhysicsStaticCollision.cs | 11 +- .../VisualPinball.Unity/Game/Player.cs | 2 +- .../Physics/Collider/ColliderRef.cs | 6 +- .../Collision/StaticCollisionSystem.cs | 2 +- .../Physics/Engine/DefaultPhysicsEngine.cs | 7 +- .../VPT/AnimationComponent.cs | 5 + .../VPT/Bumper/BumperBaker.cs | 73 -------- .../VPT/Bumper/BumperBaker.cs.meta | 3 - .../VPT/Bumper/BumperCollider.cs | 5 +- .../VPT/Bumper/BumperColliderComponent.cs | 10 +- .../VPT/Bumper/BumperComponent.cs | 62 +++++++ .../VPT/Bumper/BumperRingAnimation.cs | 51 ++++++ ...em.cs.meta => BumperRingAnimation.cs.meta} | 0 .../VPT/Bumper/BumperRingAnimationSystem.cs | 72 -------- .../VPT/Bumper/BumperRingMovementSystem.cs | 68 -------- ...ationSystem.cs => BumperSkirtAnimation.cs} | 62 +++---- ...m.cs.meta => BumperSkirtAnimation.cs.meta} | 0 .../VPT/Bumper/BumperSkirtMovementSystem.cs | 56 ------- .../Bumper/BumperSkirtMovementSystem.cs.meta | 11 -- .../VPT/Bumper/BumperState.cs | 39 +++++ .../VPT/Bumper/BumperState.cs.meta | 3 + .../VPT/Bumper/BumperTransformation.cs | 50 ++++++ ...m.cs.meta => BumperTransformation.cs.meta} | 0 .../VPT/Flipper/FlipperBaker.cs | 156 ------------------ .../VPT/Flipper/FlipperBaker.cs.meta | 3 - .../VPT/Flipper/FlipperComponent.cs | 4 +- 32 files changed, 367 insertions(+), 550 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimation.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperRingAnimationSystem.cs.meta => BumperRingAnimation.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperSkirtAnimationSystem.cs => BumperSkirtAnimation.cs} (53%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperSkirtAnimationSystem.cs.meta => BumperSkirtAnimation.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperRingMovementSystem.cs.meta => BumperTransformation.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs index c065c79f7..cb5d7feb0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs @@ -74,7 +74,7 @@ private static ref TValue GetValueByRef(this ref UnsafeParallelHas #if ENABLE_UNITY_COLLECTIONS_CHECKS if ((entryIdx < 0) || (entryIdx >= data.keyCapacity)) { - throw new KeyNotFoundException(); + throw new KeyNotFoundException("Cannot find key " + key); } #endif } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs deleted file mode 100644 index c2e9da3dc..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Unity.Entities; -using UnityEngine; -using VisualPinball.Unity; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(InitializationSystemGroup))] - internal partial class InitPlayerSystem : SystemBase - { - protected override void OnCreate() - { - base.OnCreate(); - Debug.Log($"[INIT] Created."); - - Debug.Log($"[INIT] Initializing GameObjects..."); - Entities.WithoutBurst().ForEach((Entity entity, in FlipperBaker.GameObjectContainer goc) => - { - - //var tf = EntityManager.GetComponentObject(entity); - Debug.Log($"[INIT] Initializing GameObject {goc.GameObject.name}..."); - - }).Run(); - } - - protected override void OnUpdate() - { - - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs.meta deleted file mode 100644 index 32f84601c..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/InitPlayerSystem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 6a579458cc094d218bcdf855bdcf4529 -timeCreated: 1675253461 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs index 54b18b21d..a46f39cad 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs @@ -33,6 +33,15 @@ internal static float GetFriction(this BlobAssetReference collider internal static Aabb GetAabb(this BlobAssetReference colliders, int index) => colliders.Value.Colliders[index].Value.Bounds().Aabb; + internal static unsafe ref CircleCollider GetCircleCollider(this in BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var circleCollider = (CircleCollider*) cPtr; + return ref UnsafeUtility.AsRef(circleCollider); + } + } + internal static unsafe ref PlaneCollider GetPlaneCollider(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; @@ -41,7 +50,7 @@ internal static unsafe ref PlaneCollider GetPlaneCollider(this in BlobAssetRefer return ref UnsafeUtility.AsRef(planeCollider); } } - + internal static unsafe ref LineCollider GetLineCollider(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 498e7e545..81aa0f45c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -24,7 +24,6 @@ using Unity.Jobs; using Unity.Mathematics; using UnityEngine; -using UnityEngine.Serialization; using VisualPinball.Engine.Common; using VisualPinballUnity; using Debug = UnityEngine.Debug; @@ -40,15 +39,22 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private InsideOfs _insideOfs; [NonSerialized] private NativeParallelHashMap _balls; [NonSerialized] private NativeParallelHashMap _flipperStates; + [NonSerialized] private NativeParallelHashMap _bumperStates; [NonSerialized] private readonly Dictionary _ballLookup = new(); - [NonSerialized] public readonly Dictionary FlipperLookup = new(); + [NonSerialized] private readonly Dictionary _transforms = new(); [NonSerialized] internal readonly Queue InputActions = new(); internal delegate void InputAction(ref PhysicsState state); private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); + public void Register(T item) where T : MonoBehaviour + { + var go = item.gameObject; + _transforms.Add(go.GetInstanceID(), go.transform); + } + private void Start() { var player = GetComponent(); @@ -63,17 +69,30 @@ private void Start() Debug.Log($"Found {colliderItems.Length} collidable items."); var managedColliders = new List(); foreach (var colliderItem in colliderItems) { + // todo bring GC allocations down colliderItem.GetColliders(player, managedColliders, 0); } - // data: flippers + #region Item Data + + // bumpers + var bumpers = GetComponentsInChildren(); + _bumperStates = new NativeParallelHashMap(bumpers.Length, Allocator.Persistent); + foreach (var bumper in bumpers) { + var bumperState = bumper.CreateState(); + _bumperStates[bumperState.ItemId] = bumperState; + } + + // flippers var flippers = GetComponentsInChildren(); _flipperStates = new NativeParallelHashMap(flippers.Length, Allocator.Persistent); foreach (var flipper in flippers) { - var flipperState = flipper.NewState(); + var flipperState = flipper.CreateState(); _flipperStates[flipperState.ItemId] = flipperState; } + #endregion + // allocate colliders _colliders = AllocateColliders(managedColliders); @@ -115,9 +134,11 @@ private static BlobAssetReference AllocateColliders(IEnumerable 0) { + var action = InputActions.Dequeue(); action(ref state); } + + // run physics loop updatePhysics.Run(); + // retrieve updated data _balls = updatePhysics.Balls; _physicsEnv = updatePhysics.PhysicsEnv; _flipperStates = updatePhysics.FlipperStates; + #region Movements + + // balls using (var enumerator = state.Balls.GetEnumerator()) { while (enumerator.MoveNext()) { ref var ball = ref enumerator.Current.Value; BallMovementPhysics.Move(ball, _ballLookup[ball.Id].transform); } } + + // flippers using (var enumerator = _flipperStates.GetEnumerator()) { while (enumerator.MoveNext()) { - var flipper = FlipperLookup[enumerator.Current.Key]; - flipper.transform.localRotation = quaternion.Euler(0, _flipperStates[enumerator.Current.Key].Movement.Angle, 0); + var flipperTransform = _transforms[enumerator.Current.Key]; + flipperTransform.localRotation = quaternion.Euler(0, _flipperStates[enumerator.Current.Key].Movement.Angle, 0); } } + + // bumpers + using (var enumerator = _bumperStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var bumperState = ref enumerator.Current.Value; + if (bumperState.SkirtItemId != 0) { + BumperTransformation.UpdateSkirt(in bumperState.SkirtAnimation, _transforms[bumperState.SkirtItemId]); + } + if (bumperState.RingItemId != 0) { + BumperTransformation.UpdateRing(bumperState.RingItemId, in bumperState.RingAnimation, _transforms[bumperState.RingItemId]); + } + } + } + + #endregion } private void OnDestroy() @@ -183,7 +230,11 @@ internal struct UpdatePhysicsJob : IJob { [ReadOnly] public ulong InitialTimeUsec; - [FormerlySerializedAs("PhysicsState")] public NativeArray PhysicsEnv; + + [ReadOnly] + public float DeltaTime; + + public NativeArray PhysicsEnv; public NativeOctree Octree; public BlobAssetReference Colliders; public InsideOfs InsideOfs; @@ -191,13 +242,13 @@ internal struct UpdatePhysicsJob : IJob public NativeParallelHashMap Balls; public NativeParallelHashMap FlipperStates; + public NativeParallelHashMap BumperStates; public void Execute() { var env = PhysicsEnv[0]; - var state = new PhysicsState(ref env, ref Octree, ref Colliders, ref Events, ref InsideOfs, ref Balls, ref FlipperStates); + var state = new PhysicsState(ref env, ref Octree, ref Colliders, ref Events, ref InsideOfs, ref Balls, ref FlipperStates, ref BumperStates); var cycle = new PhysicsCycle(Allocator.Temp); - var n = 0; while (env.CurPhysicsFrameTime < InitialTimeUsec) // loop here until current (real) time matches the physics (simulated) time { @@ -207,7 +258,6 @@ public void Execute() #region Update Velocities // update velocities - always on integral physics frame boundary (spinner, gate, flipper, plunger, ball) - using (var enumerator = state.Balls.GetEnumerator()) { while (enumerator.MoveNext()) { BallVelocityPhysics.UpdateVelocities(ref enumerator.Current.Value, env.Gravity); @@ -224,10 +274,25 @@ public void Execute() // primary physics loop cycle.Simulate(ref state, physicsDiffTime, timeMsec); + #region Animation + + // bumper + using (var enumerator = BumperStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var bumperState = ref enumerator.Current.Value; + if (bumperState.RingItemId != 0) { + BumperRingAnimation.Update(ref bumperState.RingAnimation, DeltaTime); + } + if (bumperState.SkirtItemId != 0) { + BumperSkirtAnimation.Update(ref bumperState.SkirtAnimation, DeltaTime); + } + } + } + + #endregion + env.CurPhysicsFrameTime = env.NextPhysicsFrameTime; env.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; - - n++; } PhysicsEnv[0] = env; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 2fc400211..d2042c6cc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -17,6 +17,7 @@ using NativeTrees; using Unity.Collections; using Unity.Entities; +using UnityEngine; using VisualPinball.Unity.Collections; namespace VisualPinball.Unity @@ -30,10 +31,11 @@ internal struct PhysicsState internal InsideOfs InsideOfs; internal NativeParallelHashMap Balls; internal NativeParallelHashMap FlipperStates; + internal NativeParallelHashMap BumperStates; public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAssetReference colliders, ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeParallelHashMap balls, - ref NativeParallelHashMap flipperStates) + ref NativeParallelHashMap flipperStates, ref NativeParallelHashMap bumperStates) { Env = env; Octree = octree; @@ -42,12 +44,21 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs InsideOfs = insideOfs; Balls = balls; FlipperStates = flipperStates; + BumperStates = bumperStates; } - internal ref FlipperState GetFlipperState(in CollisionEventData collisionEvent) + internal Collider GetCollider(int colliderId) => Colliders.Value.Colliders[colliderId].Value; + + internal ref FlipperState GetFlipperState(int colliderId) { - var collider = Colliders.Value.Colliders[collisionEvent.ColliderId].Value; + var collider = Colliders.Value.Colliders[colliderId].Value; return ref FlipperStates.GetValueByRef(collider.ItemId); } + + internal ref BumperState GetBumperState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return ref BumperStates.GetValueByRef(collider.ItemId); + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 515915f49..c2fb1c88e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -38,7 +38,11 @@ internal static void Collide(float hitTime, ref BallData ball, uint timeMs, ref private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState state) { + var collider = state.GetCollider(ball.CollisionEvent.ColliderId); switch (state.Colliders.GetType(ball.CollisionEvent.ColliderId)) { + case ColliderType.Circle: + state.Colliders.GetCircleCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); + break; case ColliderType.Plane: state.Colliders.GetPlaneCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); break; @@ -54,8 +58,13 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta case ColliderType.Point: state.Colliders.GetPointCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; + case ColliderType.Bumper: + ref var bumperState = ref state.GetBumperState(ball.CollisionEvent.ColliderId); + BumperCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref bumperState.RingAnimation, ref bumperState.SkirtAnimation, + in collider, in bumperState.Static, ref state.Env.Random); + break; case ColliderType.Flipper: - ref var flipperState = ref state.GetFlipperState(in ball.CollisionEvent); + ref var flipperState = ref state.GetFlipperState(ball.CollisionEvent.ColliderId); state.Colliders.GetFlipperCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, ref state.EventQueue, in ball.Id, in flipperState.Tricks, in flipperState.Static, in flipperState.Velocity, in flipperState.Hit, timeMs); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 89b9b8d0e..d113498be 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -227,7 +227,7 @@ public void RegisterBumper(BumperComponent component) public void RegisterFlipper(FlipperComponent component) { Register(new FlipperApi(component.gameObject, this), component); - FlipperTransforms[component.GetInstanceID()] = component.gameObject.transform; + FlipperTransforms[component.gameObject.GetInstanceID()] = component.gameObject.transform; if (EngineProvider.Exists) { EngineProvider.Get().OnRegisterFlipper(component.GetInstanceID(), component.gameObject.name); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs index aab30bf44..10b847ae6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs @@ -34,6 +34,10 @@ internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref { var hitTime = -1f; switch (_colliders.GetType(Id)) { + case ColliderType.Bumper: + case ColliderType.Circle: + hitTime = _colliders.GetCircleCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); + break; case ColliderType.Plane: hitTime = _colliders.GetPlaneCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); break; @@ -50,7 +54,7 @@ internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref hitTime = _colliders.GetPointCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); break; case ColliderType.Flipper: - var flipperState = state.GetFlipperState(in collEvent); + ref var flipperState = ref state.GetFlipperState(Id); hitTime = _colliders.GetFlipperCollider(Id).HitTest( ref collEvent, ref state.InsideOfs, ref flipperState.Hit, in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs index 1f189c746..163330026 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs @@ -103,7 +103,7 @@ protected override void OnUpdate() var ringData = animateRing ? GetComponent(coll.ItemId) : default; var skirtData = animateSkirt ? GetComponent(coll.ItemId): default; BumperCollider.Collide(ref ballData, ref events, ref collEvent, ref ringData, ref skirtData, - in ballId, in coll, bumperStaticData, ref random); + in coll, bumperStaticData, ref random); if (animateRing) { SetComponent(coll.ItemId, ringData); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs index 8dab7283c..b0560b0d8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs @@ -21,6 +21,7 @@ using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Common; +using VisualPinball.Unity.Collections; using VisualPinballUnity; namespace VisualPinball.Unity @@ -104,12 +105,11 @@ public void FlipperRotateToEnd(in int itemId) var physicsEngine = _tableComponent.GetComponent(); physicsEngine.InputActions.Enqueue((ref PhysicsState state) => { var timeMsec = (uint)((state.Env.CurPhysicsFrameTime - state.Env.StartTimeUsec) / 1000); - var flipperState = state.FlipperStates[id]; + ref var flipperState = ref state.FlipperStates.GetValueByRef(id); flipperState.Movement.EnableRotateEvent = 1; flipperState.Movement.StartRotateToEndTime = timeMsec; flipperState.Movement.AngleAtRotateToEnd = flipperState.Movement.Angle; flipperState.Solenoid.Value = true; - state.FlipperStates[id] = flipperState; }); } @@ -119,10 +119,9 @@ public void FlipperRotateToStart(in int itemId) var physicsEngine = _tableComponent.GetComponent(); physicsEngine.InputActions.Enqueue((ref PhysicsState state) => { var timeMsec = (uint)((state.Env.CurPhysicsFrameTime - state.Env.StartTimeUsec) / 1000); - var flipperState = state.FlipperStates[id]; + ref var flipperState = ref state.FlipperStates.GetValueByRef(id); flipperState.Movement.EnableRotateEvent = -1; flipperState.Solenoid.Value = false; - state.FlipperStates[id] = flipperState; }); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs index ea1b45623..df485b9ca 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs @@ -27,6 +27,11 @@ public abstract class AnimationComponent : SubComponent MainComponent.UpdateTransforms(); + private void Awake() + { + GetComponentInParent().Register(this); + } + private Entity MainEntity { get { var ma = MainComponent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs deleted file mode 100644 index 034f8fd6f..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Mathematics; -using VisualPinball.Engine.VPT.Bumper; - -namespace VisualPinball.Unity -{ - public class BumperBaker : ItemBaker - { - public override void Bake(BumperComponent authoring) - { - base.Bake(authoring); - - // physics collision data - var collComponent = GetComponentInChildren(); - if (collComponent) { - AddComponent(new BumperStaticData { - Force = collComponent.Force, - HitEvent = collComponent.HitEvent, - Threshold = collComponent.Threshold - }); - } - - // skirt animation data - if (GetComponentInChildren()) { - AddComponent(new BumperSkirtAnimationData { - BallPosition = default, - AnimationCounter = 0f, - DoAnimate = false, - DoUpdate = false, - EnableAnimation = true, - Rotation = new float2(0, 0), - Center = authoring.Position - }); - } - - // ring animation data - var ringAnimComponent = GetComponentInChildren(); - if (ringAnimComponent) { - AddComponent(new BumperRingAnimationData { - - // dynamic - IsHit = false, - Offset = 0, - AnimateDown = false, - DoAnimate = false, - - // static - DropOffset = ringAnimComponent.RingDropOffset, - HeightScale = authoring.HeightScale, - Speed = ringAnimComponent.RingSpeed, - }); - } - - // register at player - GetComponentInParent().RegisterBumper(authoring); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs.meta deleted file mode 100644 index f2dd7c3af..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 209394c940da47d28fa72de81c7330f4 -timeCreated: 1673022285 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs index c166b36c5..f5832f36e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Game; @@ -25,7 +24,7 @@ internal static class BumperCollider { public static void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, ref CollisionEventData collEvent, ref BumperRingAnimationData ringData, ref BumperSkirtAnimationData skirtData, - in int ballId, in Collider collider, in BumperStaticData data, ref Random random) + in Collider collider, in BumperStaticData data, ref Random random) { // todo // if (!m_enabled) return; @@ -42,7 +41,7 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle skirtData.HitEvent = true; skirtData.BallPosition = ball.Position; - events.Enqueue(new EventData(EventId.HitEventsHit, collider.ItemId, ballId, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, collider.ItemId, ball.Id, true)); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs index e30b95b83..7372013a6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs @@ -16,14 +16,14 @@ // ReSharper disable InconsistentNaming -using Unity.Entities; +using System.Collections.Generic; using UnityEngine; using VisualPinball.Engine.VPT.Bumper; namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Collision/Bumper Collider")] - public class BumperColliderComponent : ColliderComponent + public class BumperColliderComponent : ColliderComponent, ICollidableComponent { #region Data @@ -47,6 +47,12 @@ public class BumperColliderComponent : ColliderComponent new BumperApi(gameObject, player); + + void ICollidableComponent.GetColliders(Player player, List colliders, float margin) + { + InstantiateColliderApi(player).CreateColliders(colliders, margin); + } + public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(scatterAngleDeg: Scatter); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs index a0c13a4e3..8d5800f6a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs @@ -83,6 +83,17 @@ public class BumperComponent : MainRenderableComponent, #endregion + #region Runtime + + private void Awake() + { + // register at player + GetComponentInParent().RegisterBumper(this); + GetComponentInParent().Register(this); + } + + #endregion + #region Wiring public IEnumerable AvailableSwitches => new[] { @@ -284,6 +295,57 @@ public override void CopyFromObject(GameObject go) UpdateTransforms(); } + internal BumperState CreateState() + { + // physics collision data + var collComponent = GetComponentInChildren(); + var staticData = collComponent + ? new BumperStaticData { + Force = collComponent.Force, + HitEvent = collComponent.HitEvent, + Threshold = collComponent.Threshold + } : default; + + // skirt animation data + var skirtAnimComponent = GetComponentInChildren(); + var skirtAnimation = skirtAnimComponent + ? new BumperSkirtAnimationData { + BallPosition = default, + AnimationCounter = 0f, + DoAnimate = false, + DoUpdate = false, + EnableAnimation = true, + Rotation = new float2(0, 0), + Center = Position + } : default; + + // ring animation data + var ringAnimComponent = GetComponentInChildren(); + var ringAnimation = ringAnimComponent + ? new BumperRingAnimationData { + + // dynamic + IsHit = false, + Offset = 0, + AnimateDown = false, + DoAnimate = false, + + // static + DropOffset = ringAnimComponent.RingDropOffset, + HeightScale = HeightScale, + Speed = ringAnimComponent.RingSpeed, + } : default; + + return new BumperState( + collComponent ? gameObject.GetInstanceID() : 0, + skirtAnimComponent ? skirtAnimComponent.gameObject.GetInstanceID() : 0, + ringAnimComponent ? ringAnimComponent.gameObject.GetInstanceID() : 0, + staticData, + ringAnimation, + skirtAnimation + ); + } + #endregion #region Editor Tooling diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimation.cs new file mode 100644 index 000000000..1ccbd4d61 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimation.cs @@ -0,0 +1,51 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal static class BumperRingAnimation + { + internal static void Update(ref BumperRingAnimationData data, float dTime) + { + // todo visibility - skip if invisible + + var limit = data.DropOffset + data.HeightScale * 0.5f; + if (data.IsHit) { + data.DoAnimate = true; + data.AnimateDown = true; + data.IsHit = false; + } + if (data.DoAnimate) { + var step = data.Speed; + if (data.AnimateDown) { + step = -step; + } + data.Offset += step * dTime; + if (data.AnimateDown) { + if (data.Offset <= -limit) { + data.Offset = -limit; + data.AnimateDown = false; + } + } else { + if (data.Offset >= 0.0f) { + data.Offset = 0.0f; + data.DoAnimate = false; + } + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimation.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimation.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs deleted file mode 100644 index f3695f7b8..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationSystem.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Profiling; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class BumperRingAnimationSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperRingAnimationSystem"); - - protected override void OnUpdate() - { - var dTime = SystemAPI.Time.DeltaTime * 1000; - var marker = PerfMarker; - - Entities - .WithName("BumperRingAnimationJob") - .ForEach((ref BumperRingAnimationData data) => { - - // todo visibility - skip if invisible - - marker.Begin(); - - var limit = data.DropOffset + data.HeightScale * 0.5f; - if (data.IsHit) { - data.DoAnimate = true; - data.AnimateDown = true; - data.IsHit = false; - } - if (data.DoAnimate) { - var step = data.Speed; - if (data.AnimateDown) { - step = -step; - } - data.Offset += step * dTime; - if (data.AnimateDown) { - if (data.Offset <= -limit) { - data.Offset = -limit; - data.AnimateDown = false; - } - } else { - if (data.Offset >= 0.0f) { - data.Offset = 0.0f; - data.DoAnimate = false; - } - } - } - - marker.End(); - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs deleted file mode 100644 index b52766951..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System.Collections.Generic; -using Unity.Entities; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -using Physics = UnityEngine.Physics; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class BumperRingMovementSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperRingMovementSystem"); - - private Player _player; - - private readonly Dictionary _initialOffset = new(); - - protected override void OnStartRunning() - { - base.OnStartRunning(); - _player = Object.FindObjectOfType(); - } - - protected override void OnUpdate() - { - // fixme job - // var marker = PerfMarker; - // Entities.WithoutBurst().WithName("BumperRingMovementJob").ForEach((Entity entity, in BumperRingAnimationData data) => { - // - // marker.Begin(); - // - // var transform = _player.BumperRingTransforms[entity]; - // if (!_initialOffset.ContainsKey(entity)) { - // _initialOffset[entity] = transform.position.y; - // } - // - // var limit = data.DropOffset + data.HeightScale * 0.5f; - // var localLimit = _initialOffset[entity] + limit; - // var localOffset = localLimit / limit * data.Offset; - // - // var worldPos = transform.position; - // worldPos.y = _initialOffset[entity] + VisualPinball.Unity.Physics.ScaleToWorld(localOffset); - // transform.position = worldPos; - // - // marker.End(); - // - // }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimation.cs similarity index 53% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimation.cs index 45731c7d0..7dd959838 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimation.cs @@ -14,56 +14,36 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; -using Unity.Profiling; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -namespace VisualPinballUnity +namespace VisualPinball.Unity { - [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class BumperSkirtAnimationSystem : SystemBaseStub + internal static class BumperSkirtAnimation { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperSkirtAnimationSystem"); - - protected override void OnUpdate() + internal static void Update(ref BumperSkirtAnimationData data, float dTime) { - var dTime = SystemAPI.Time.DeltaTime * 1000; - var marker = PerfMarker; - - Entities - .WithName("BumperSkirtAnimationJob") - .ForEach((ref BumperSkirtAnimationData data) => { - - // todo visibility - skip if invisible - - marker.Begin(); + // todo visibility - skip if invisible - var isHit = data.HitEvent; - data.HitEvent = false; + var isHit = data.HitEvent; + data.HitEvent = false; - if (data.EnableAnimation) { - if (isHit) { - data.DoAnimate = true; - UpdateSkirt(ref data); - data.AnimationCounter = 0.0f; - } - if (data.DoAnimate) { - data.AnimationCounter += dTime; - if (data.AnimationCounter > 160.0f) { - data.DoAnimate = false; - ResetSkirt(ref data); - } - } - } else if (data.DoUpdate) { // do a single update if the animation was turned off via script - data.DoUpdate = false; + if (data.EnableAnimation) { + if (isHit) { + data.DoAnimate = true; + UpdateSkirt(ref data); + data.AnimationCounter = 0.0f; + } + if (data.DoAnimate) { + data.AnimationCounter += dTime; + if (data.AnimationCounter > 160.0f) { + data.DoAnimate = false; ResetSkirt(ref data); } - - marker.End(); - - }).Run(); + } + } else if (data.DoUpdate) { // do a single update if the animation was turned off via script + data.DoUpdate = false; + ResetSkirt(ref data); + } } private static void UpdateSkirt(ref BumperSkirtAnimationData data) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimation.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimation.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs deleted file mode 100644 index 13369a26f..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class BumperSkirtMovementSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BumperSkirtMovementSystem"); - - private Player _player; - - protected override void OnStartRunning() - { - base.OnStartRunning(); - _player = Object.FindObjectOfType(); - } - - protected override void OnUpdate() - { - // fixme job - // var marker = PerfMarker; - // Entities.WithoutBurst().WithName("BumperSkirtMovementJob").ForEach((Entity entity, in BumperSkirtAnimationData data) => { - // - // marker.Begin(); - // - // var transform = _player.BumperSkirtTransforms[entity]; - // var parentRotation = transform.parent.rotation; - // transform.rotation = Quaternion.Euler(data.Rotation.x, 0, -data.Rotation.y) * parentRotation; - // - // marker.End(); - // - // }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs.meta deleted file mode 100644 index 386e8a21e..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtMovementSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3890dfd771cce314a8949d8cc9bc5cf7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs new file mode 100644 index 000000000..6ecbdf3c3 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs @@ -0,0 +1,39 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal struct BumperState + { + internal readonly int ItemId; + internal readonly int SkirtItemId; + internal int RingItemId; + internal BumperStaticData Static; + internal BumperRingAnimationData RingAnimation; + internal BumperSkirtAnimationData SkirtAnimation; + + public BumperState(int itemId, int skirtItemId, int ringItemId, BumperStaticData @static, + BumperRingAnimationData ringAnimation, BumperSkirtAnimationData skirtAnimation) + { + ItemId = itemId; + SkirtItemId = skirtItemId; + RingItemId = ringItemId; + Static = @static; + RingAnimation = ringAnimation; + SkirtAnimation = skirtAnimation; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs.meta new file mode 100644 index 000000000..8cad9513c --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 84922bfe360d4d3598dbf85749eb2173 +timeCreated: 1696418720 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs new file mode 100644 index 000000000..753de2cc8 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs @@ -0,0 +1,50 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using Unity.Entities; +using Unity.Profiling; +using UnityEngine; +using VisualPinball.Unity; +using VisualPinball.Unity.VisualPinball.Unity.Game; +using Physics = UnityEngine.Physics; + +namespace VisualPinballUnity +{ + internal static class BumperTransformation + { + private static readonly Dictionary InitialOffset = new(); + + internal static void UpdateRing(int itemId, in BumperRingAnimationData data, Transform transform) + { + var worldPos = transform.position; + InitialOffset.TryAdd(itemId, worldPos.y); + + var limit = data.DropOffset + data.HeightScale * 0.5f; + var localLimit = InitialOffset[itemId] + limit; + var localOffset = localLimit / limit * data.Offset; + + worldPos.y = InitialOffset[itemId] + VisualPinball.Unity.Physics.ScaleToWorld(localOffset); + transform.position = worldPos; + } + + internal static void UpdateSkirt(in BumperSkirtAnimationData data, Transform transform) + { + var parentRotation = transform.parent.rotation; + transform.rotation = Quaternion.Euler(data.Rotation.x, 0, -data.Rotation.y) * parentRotation; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingMovementSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs deleted file mode 100644 index 0aa7d56b9..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs +++ /dev/null @@ -1,156 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using Unity.Collections; -using Unity.Entities; -using UnityEngine; -using VisualPinball.Engine.Math; -using VisualPinball.Engine.VPT.Flipper; -using VisualPinball.Engine.VPT.Trigger; - -namespace VisualPinball.Unity -{ - public class FlipperBaker : ItemBaker - { - public override void Bake(FlipperComponent authoring) - { - base.Bake(authoring); - - var player = GetComponentInParent(); - var colliderComponent = GetComponent(); - - // collision - if (colliderComponent) { - - // vpx physics - var d = authoring.GetMaterialData(colliderComponent); - AddComponent(d); - AddComponent(authoring.GetMovementData(d)); - AddComponent(FlipperComponent.GetVelocityData(d)); - AddComponent(authoring.GetHitData()); - AddComponent(authoring.GetFlipperTricksData(colliderComponent, d)); - AddComponent(new SolenoidStateData { Value = false }); - AddComponentObject(new GameObjectContainer { GameObject = authoring.gameObject }); - - // flipper correction (nFozzy) - if (colliderComponent.FlipperCorrection) { - SetupFlipperCorrection(authoring, player, colliderComponent); - } - } - - // register - player.RegisterFlipper(authoring); - } - - private void SetupFlipperCorrection(FlipperComponent authoring, Player player, FlipperColliderComponent colliderComponent) - { - var fc = colliderComponent.FlipperCorrection; - - // create trigger - var triggerData = CreateCorrectionTriggerData(authoring); - var triggerEntity = CreateAdditionalEntity(); - AddComponent(triggerEntity, new TriggerStaticData()); - // todo add proper colliders - //player.RegisterTrigger(triggerData, triggerEntity, authoring.gameObject); - - using (var builder = new BlobBuilder(Allocator.Temp)) { - - ref var root = ref builder.ConstructRoot(); - root.FlipperEntity = GetEntity(); - root.TimeDelayMs = fc.TimeThresholdMs; - - // Discretize the curves - var polarities = builder.Allocate(ref root.Polarities, fc.PolaritiesCurveSlicingCount + 1); - if (fc.Polarities != null) - { - var curve = fc.Polarities; - float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.PolaritiesCurveSlicingCount; - int i = 0; - for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) - { - polarities[i].x = t; - polarities[i++].y = curve.Evaluate(t); - } - } - else - { - for (int i = 0; i < fc.PolaritiesCurveSlicingCount + 1; i++) - { - polarities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; - polarities[i].y = 0F; - } - } - - var velocities = builder.Allocate(ref root.Velocities, fc.VelocitiesCurveSlicingCount + 1); - if (fc.Velocities != null) - { - var curve = fc.Velocities; - float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.VelocitiesCurveSlicingCount; - int i = 0; - for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) - { - velocities[i].x = t; - velocities[i++].y = curve.Evaluate(t); - } - } - else - { - for (int i = 0; i < fc.VelocitiesCurveSlicingCount + 1; i++) - { - velocities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; - velocities[i].y = 1F; - } - } - - var blobAssetRef = builder.CreateBlobAssetReference(Allocator.Persistent); - - // add correction data - AddComponent(triggerEntity, new FlipperCorrectionData { - Value = blobAssetRef - }); - } - } - - public TriggerData CreateCorrectionTriggerData(FlipperComponent authoring) - { - // Get table reference - var ta = GetComponentInParent(); - if (ta != null) { - - var localPos = authoring.transform.localPosition; - var data = new TriggerData(authoring.name + " (Correction Trigger)", localPos.x, localPos.y); - var poly = authoring.GetEnclosingPolygon(23, 12); - data.DragPoints = new DragPointData[poly.Count]; - data.IsLocked = true; - data.HitHeight = 150F; // nFozzy's recommendation, but I think 50 should be ok - - for (var i = 0; i < poly.Count; i++) { - // Poly points are expressed in flipper's frame: transpose to Table's frame as this is the basis uses for drag points - var p = ta.transform.InverseTransformPoint(authoring.transform.TransformPoint(poly[i])); - data.DragPoints[poly.Count - i - 1] = new DragPointData(p.x, p.y); - } - return data; - } - throw new InvalidOperationException("Cannot create correction trigger for flipper outside of the table hierarchy."); - } - - internal class GameObjectContainer : IComponentData - { - public GameObject GameObject; - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs.meta deleted file mode 100644 index 45bdaceb2..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: e5d44d70389a4e5a88256364ec7512cf -timeCreated: 1673020322 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index 1fc9193de..d9feab46c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -477,7 +477,7 @@ private void Awake() { _originalRotateZ = _startAngle; GetComponentInParent().RegisterFlipper(this); - GetComponentInParent().FlipperLookup.Add(gameObject.GetInstanceID(), gameObject); + GetComponentInParent().Register(this); } private void Start() @@ -489,7 +489,7 @@ private void Start() #region DOTS Data - internal FlipperState NewState() + internal FlipperState CreateState() { var colliderComponent = gameObject.GetComponent(); // collision From a25ae748fb1daa2e4c6b92f0bdb64de9fd55f4db Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 4 Oct 2023 23:55:15 +0200 Subject: [PATCH 060/159] jobs: Minor cleanup. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 18 ++++++++----- .../Collision/StaticCollisionSystem.cs | 26 +++++++++---------- .../Physics/Engine/DefaultPhysicsEngine.cs | 5 ++-- .../VPT/Bumper/BumperApi.cs | 1 - .../VPT/Bumper/BumperRingAnimationData.cs | 4 +-- .../VPT/Bumper/BumperSkirtAnimationData.cs | 4 +-- .../VPT/Bumper/BumperStaticData.cs | 4 +-- ...erTransformation.cs => BumperTransform.cs} | 14 +++++----- ...mation.cs.meta => BumperTransform.cs.meta} | 0 9 files changed, 36 insertions(+), 40 deletions(-) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperTransformation.cs => BumperTransform.cs} (79%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperTransformation.cs.meta => BumperTransform.cs.meta} (100%) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 81aa0f45c..88708f474 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -32,6 +32,8 @@ namespace VisualPinball.Unity { public class PhysicsEngine : MonoBehaviour { + internal delegate void InputAction(ref PhysicsState state); + [NonSerialized] private NativeArray _physicsEnv; [NonSerialized] private NativeOctree _octree; [NonSerialized] private BlobAssetReference _colliders; @@ -44,8 +46,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private readonly Dictionary _ballLookup = new(); [NonSerialized] private readonly Dictionary _transforms = new(); - [NonSerialized] internal readonly Queue InputActions = new(); - internal delegate void InputAction(ref PhysicsState state); + [NonSerialized] private readonly Queue _inputActions = new(); private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); @@ -55,6 +56,11 @@ public void Register(T item) where T : MonoBehaviour _transforms.Add(go.GetInstanceID(), go.transform); } + internal void Schedule(InputAction action) + { + _inputActions.Enqueue(action); + } + private void Start() { var player = GetComponent(); @@ -153,8 +159,8 @@ private void Update() var state = new PhysicsState(ref env, ref _octree, ref _colliders, ref events, ref _insideOfs, ref _balls, ref _flipperStates, ref _bumperStates); // process input - while (InputActions.Count > 0) { - var action = InputActions.Dequeue(); + while (_inputActions.Count > 0) { + var action = _inputActions.Dequeue(); action(ref state); } @@ -189,10 +195,10 @@ private void Update() while (enumerator.MoveNext()) { ref var bumperState = ref enumerator.Current.Value; if (bumperState.SkirtItemId != 0) { - BumperTransformation.UpdateSkirt(in bumperState.SkirtAnimation, _transforms[bumperState.SkirtItemId]); + BumperTransform.UpdateSkirt(in bumperState.SkirtAnimation, _transforms[bumperState.SkirtItemId]); } if (bumperState.RingItemId != 0) { - BumperTransformation.UpdateRing(bumperState.RingItemId, in bumperState.RingAnimation, _transforms[bumperState.RingItemId]); + BumperTransform.UpdateRing(bumperState.RingItemId, in bumperState.RingAnimation, _transforms[bumperState.RingItemId]); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs index 163330026..9be357738 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs @@ -97,19 +97,19 @@ protected override void OnUpdate() switch (coll.Type) { case ColliderType.Bumper: { - var bumperStaticData = GetComponent(coll.ItemId); - var animateRing = HasComponent(coll.ItemId); - var animateSkirt = HasComponent(coll.ItemId); - var ringData = animateRing ? GetComponent(coll.ItemId) : default; - var skirtData = animateSkirt ? GetComponent(coll.ItemId): default; - BumperCollider.Collide(ref ballData, ref events, ref collEvent, ref ringData, ref skirtData, - in coll, bumperStaticData, ref random); - if (animateRing) { - SetComponent(coll.ItemId, ringData); - } - if (animateSkirt) { - SetComponent(coll.ItemId, skirtData); - } + // var bumperStaticData = GetComponent(coll.ItemId); + // var animateRing = HasComponent(coll.ItemId); + // var animateSkirt = HasComponent(coll.ItemId); + // var ringData = animateRing ? GetComponent(coll.ItemId) : default; + // var skirtData = animateSkirt ? GetComponent(coll.ItemId): default; + // BumperCollider.Collide(ref ballData, ref events, ref collEvent, ref ringData, ref skirtData, + // in coll, bumperStaticData, ref random); + // if (animateRing) { + // SetComponent(coll.ItemId, ringData); + // } + // if (animateSkirt) { + // SetComponent(coll.ItemId, skirtData); + // } break; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs index b0560b0d8..726d28e18 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs @@ -103,7 +103,7 @@ public void FlipperRotateToEnd(in int itemId) { var id = itemId; var physicsEngine = _tableComponent.GetComponent(); - physicsEngine.InputActions.Enqueue((ref PhysicsState state) => { + physicsEngine.Schedule((ref PhysicsState state) => { var timeMsec = (uint)((state.Env.CurPhysicsFrameTime - state.Env.StartTimeUsec) / 1000); ref var flipperState = ref state.FlipperStates.GetValueByRef(id); flipperState.Movement.EnableRotateEvent = 1; @@ -117,8 +117,7 @@ public void FlipperRotateToStart(in int itemId) { var id = itemId; var physicsEngine = _tableComponent.GetComponent(); - physicsEngine.InputActions.Enqueue((ref PhysicsState state) => { - var timeMsec = (uint)((state.Env.CurPhysicsFrameTime - state.Env.StartTimeUsec) / 1000); + physicsEngine.Schedule((ref PhysicsState state) => { ref var flipperState = ref state.FlipperStates.GetValueByRef(id); flipperState.Movement.EnableRotateEvent = -1; flipperState.Solenoid.Value = false; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs index cb272b4bf..591985c0d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs @@ -16,7 +16,6 @@ using System; using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Bumper; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationData.cs index dbbffb1fe..fd02a86f1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct BumperRingAnimationData : IComponentData + internal struct BumperRingAnimationData { public bool IsHit; public float DropOffset; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationData.cs index 0ea2c9e34..0f64ae026 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationData.cs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; namespace VisualPinball.Unity { - internal struct BumperSkirtAnimationData : IComponentData + internal struct BumperSkirtAnimationData { // dynamic public bool HitEvent; @@ -32,6 +31,5 @@ internal struct BumperSkirtAnimationData : IComponentData // static public float2 Center; - } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticData.cs index b80e2430d..9b7f255fc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct BumperStaticData : IComponentData + internal struct BumperStaticData { public float Force; public float Threshold; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransform.cs similarity index 79% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransform.cs index 753de2cc8..db36deacb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransform.cs @@ -15,16 +15,14 @@ // along with this program. If not, see . using System.Collections.Generic; -using Unity.Entities; -using Unity.Profiling; using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -using Physics = UnityEngine.Physics; -namespace VisualPinballUnity +namespace VisualPinball.Unity { - internal static class BumperTransformation + /// + /// Applies the state to the scene, aka the transform of the game objects. + /// + internal static class BumperTransform { private static readonly Dictionary InitialOffset = new(); @@ -37,7 +35,7 @@ internal static void UpdateRing(int itemId, in BumperRingAnimationData data, Tra var localLimit = InitialOffset[itemId] + limit; var localOffset = localLimit / limit * data.Offset; - worldPos.y = InitialOffset[itemId] + VisualPinball.Unity.Physics.ScaleToWorld(localOffset); + worldPos.y = InitialOffset[itemId] + Physics.ScaleToWorld(localOffset); transform.position = worldPos; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransform.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransformation.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransform.cs.meta From c58881ddbe95188120d131bfb60a87dc348238c8 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 5 Oct 2023 00:28:52 +0200 Subject: [PATCH 061/159] jobs: Add state data to remaining items. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 48 ++++---- .../Physics/Collision/LineSlingshotData.cs | 4 +- .../VPT/Bumper/BumperComponent.cs | 8 +- .../VisualPinball.Unity/VPT/Gate/GateBaker.cs | 60 ---------- .../VPT/Gate/GateBaker.cs.meta | 3 - .../VPT/Gate/GateComponent.cs | 52 +++++++++ .../VPT/Gate/GateMovementData.cs | 4 +- .../SurfaceBaker.cs => Gate/GateState.cs} | 73 ++++++------ .../VPT/Gate/GateState.cs.meta | 3 + .../VPT/Gate/GateStaticData.cs | 4 +- .../VPT/HitTarget/DropTargetAnimationData.cs | 4 +- .../VPT/HitTarget/DropTargetBaker.cs | 48 -------- .../VPT/HitTarget/DropTargetBaker.cs.meta | 3 - .../VPT/HitTarget/DropTargetComponent.cs | 44 ++++++++ .../VPT/HitTarget/DropTargetState.cs | 34 ++++++ .../VPT/HitTarget/DropTargetState.cs.meta | 3 + .../VPT/HitTarget/DropTargetStaticData.cs | 4 +- .../VPT/HitTarget/HitTargetAnimationData.cs | 4 +- .../VPT/HitTarget/HitTargetBaker.cs | 45 -------- .../VPT/HitTarget/HitTargetBaker.cs.meta | 3 - .../VPT/HitTarget/HitTargetComponent.cs | 40 +++++++ .../VPT/HitTarget/HitTargetState.cs | 34 ++++++ .../VPT/HitTarget/HitTargetState.cs.meta | 3 + .../VPT/HitTarget/HitTargetStaticData.cs | 4 +- .../VPT/Kicker/KickerComponent.cs | 51 +++++++++ .../VPT/Kicker/KickerState.cs | 32 ++++++ .../VPT/Kicker/KickerState.cs.meta | 3 + .../VPT/Plunger/PlungerAnimationData.cs | 4 +- .../VPT/Plunger/PlungerBaker.cs | 106 ------------------ .../VPT/Plunger/PlungerBaker.cs.meta | 3 - .../VPT/Plunger/PlungerColliderData.cs | 4 +- .../VPT/Plunger/PlungerComponent.cs | 92 ++++++++++++++- .../VPT/Plunger/PlungerMovementData.cs | 4 +- .../VPT/Plunger/PlungerState.cs | 38 +++++++ .../VPT/Plunger/PlungerState.cs.meta | 3 + .../VPT/Plunger/PlungerStaticData.cs | 4 +- .../VPT/Plunger/PlungerVelocityData.cs | 4 +- .../VPT/Spinner/SpinnerBaker.cs | 55 --------- .../VPT/Spinner/SpinnerBaker.cs.meta | 3 - .../VPT/Spinner/SpinnerComponent.cs | 46 ++++++++ .../VPT/Spinner/SpinnerMovementData.cs | 4 +- .../VPT/Spinner/SpinnerState.cs | 34 ++++++ .../VPT/Spinner/SpinnerState.cs.meta | 3 + .../VPT/Spinner/SpinnerStaticData.cs | 4 +- .../VPT/Surface/SurfaceBaker.cs.meta | 3 - .../VPT/Surface/SurfaceComponent.cs | 31 +++++ .../VPT/Surface/SurfaceState.cs | 30 +++++ .../VPT/Surface/SurfaceState.cs.meta | 3 + .../VPT/Trigger/TriggerAnimationData.cs | 4 +- .../VPT/Trigger/TriggerBaker.cs | 45 -------- .../VPT/Trigger/TriggerBaker.cs.meta | 3 - .../VPT/Trigger/TriggerComponent.cs | 37 ++++++ .../VPT/Trigger/TriggerMovementData.cs | 4 +- .../VPT/Trigger/TriggerState.cs | 36 ++++++ .../VPT/Trigger/TriggerState.cs.meta | 3 + .../VPT/Trigger/TriggerStaticData.cs | 4 +- 56 files changed, 736 insertions(+), 496 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs.meta rename VisualPinball.Unity/VisualPinball.Unity/VPT/{Surface/SurfaceBaker.cs => Gate/GateState.cs} (58%) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetState.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetState.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 88708f474..6a0393951 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -40,8 +40,15 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeQueue _eventQueue; [NonSerialized] private InsideOfs _insideOfs; [NonSerialized] private NativeParallelHashMap _balls; - [NonSerialized] private NativeParallelHashMap _flipperStates; - [NonSerialized] private NativeParallelHashMap _bumperStates; + [NonSerialized] private NativeParallelHashMap _bumperStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashMap _flipperStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashMap _gateStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashMap _dropTargetStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashMap _hitTargetStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashMap _kickerStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashMap _plungerStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashMap _spinnerStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashMap _surfaceStates = new(0, Allocator.Persistent); [NonSerialized] private readonly Dictionary _ballLookup = new(); [NonSerialized] private readonly Dictionary _transforms = new(); @@ -50,10 +57,23 @@ public class PhysicsEngine : MonoBehaviour private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); - public void Register(T item) where T : MonoBehaviour + internal void Register(T item) where T : MonoBehaviour { var go = item.gameObject; - _transforms.Add(go.GetInstanceID(), go.transform); + var itemId = go.GetInstanceID(); + _transforms.Add(itemId, go.transform); + + switch (item) { + case BumperComponent c: _bumperStates[itemId] = c.CreateState(); break; + case FlipperComponent c: _flipperStates[itemId] = c.CreateState(); break; + case GateComponent c: _gateStates[itemId] = c.CreateState(); break; + case DropTargetComponent c: _dropTargetStates[itemId] = c.CreateState(); break; + case HitTargetComponent c: _hitTargetStates[itemId] = c.CreateState(); break; + case KickerComponent c: _kickerStates[itemId] = c.CreateState(); break; + case PlungerComponent c: _plungerStates[itemId] = c.CreateState(); break; + case SpinnerComponent c: _spinnerStates[itemId] = c.CreateState(); break; + case SurfaceComponent c: _surfaceStates[itemId] = c.CreateState(); break; + } } internal void Schedule(InputAction action) @@ -79,26 +99,6 @@ private void Start() colliderItem.GetColliders(player, managedColliders, 0); } - #region Item Data - - // bumpers - var bumpers = GetComponentsInChildren(); - _bumperStates = new NativeParallelHashMap(bumpers.Length, Allocator.Persistent); - foreach (var bumper in bumpers) { - var bumperState = bumper.CreateState(); - _bumperStates[bumperState.ItemId] = bumperState; - } - - // flippers - var flippers = GetComponentsInChildren(); - _flipperStates = new NativeParallelHashMap(flippers.Length, Allocator.Persistent); - foreach (var flipper in flippers) { - var flipperState = flipper.CreateState(); - _flipperStates[flipperState.ItemId] = flipperState; - } - - #endregion - // allocate colliders _colliders = AllocateColliders(managedColliders); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotData.cs index 280313729..169624a3e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct LineSlingshotData : IComponentData + internal struct LineSlingshotData { public bool IsDisabled; public float Threshold; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs index 8d5800f6a..1da2039b7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs @@ -89,7 +89,9 @@ private void Awake() { // register at player GetComponentInParent().RegisterBumper(this); - GetComponentInParent().Register(this); + if (GetComponentInChildren()) { + GetComponentInParent().Register(this); + } } #endregion @@ -295,6 +297,10 @@ public override void CopyFromObject(GameObject go) UpdateTransforms(); } + #endregion + + #region State + internal BumperState CreateState() { // physics collision data diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs deleted file mode 100644 index f339fe06b..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Mathematics; -using UnityEngine.UIElements; -using VisualPinball.Engine.Common; -using VisualPinball.Engine.VPT.Gate; - -namespace VisualPinball.Unity -{ - public class GateBaker : ItemBaker - { - public override void Bake(GateComponent authoring) - { - base.Bake(authoring); - - // collision - var colliderComponent = GetComponent(); - if (colliderComponent) { - - AddComponent(new GateStaticData { - AngleMin = math.radians(colliderComponent._angleMin), - AngleMax = math.radians(colliderComponent._angleMax), - Height = authoring.Position.z, - Damping = math.pow(colliderComponent.Damping, (float)PhysicsConstants.PhysFactor), - GravityFactor = colliderComponent.GravityFactor, - TwoWay = colliderComponent.TwoWay, - }); - - // movement data - if (GetComponentInChildren()) { - AddComponent(new GateMovementData { - Angle = math.radians(colliderComponent._angleMin), - AngleSpeed = 0, - ForcedMove = false, - IsOpen = false, - HitDirection = false - }); - } - } - - // register - GetComponentInParent().RegisterGate(authoring); - - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs.meta deleted file mode 100644 index da4e328ec..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 940446727b09426b908921cde61994f0 -timeCreated: 1673022636 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs index f1241c426..7a3d62f03 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs @@ -27,9 +27,12 @@ using Unity.Mathematics; using UnityEditor; using UnityEngine; +using UnityEngine.UIElements; +using VisualPinball.Engine.Common; using VisualPinball.Engine.Game.Engines; using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.Gate; +using VisualPinball.Engine.VPT.Surface; using VisualPinball.Engine.VPT.Table; namespace VisualPinball.Unity @@ -102,6 +105,19 @@ public bool ShowBracket { get { #endregion + #region Runtime + + private void Awake() + { + // register at player + GetComponentInParent().RegisterGate(this); + if (GetComponent()) { + GetComponentInParent().Register(this); + } + } + + #endregion + #region Wiring public IEnumerable AvailableSwitches => new[] { @@ -263,6 +279,42 @@ public override void CopyFromObject(GameObject go) #endregion + #region State + + internal GateState CreateState() + { + // collision + var collComponent = GetComponent(); + var staticData = collComponent + ? new GateStaticData { + AngleMin = math.radians(collComponent._angleMin), + AngleMax = math.radians(collComponent._angleMax), + Height = Position.z, + Damping = math.pow(collComponent.Damping, (float)PhysicsConstants.PhysFactor), + GravityFactor = collComponent.GravityFactor, + TwoWay = collComponent.TwoWay, + } : default; + + var wireComponent = GetComponentInChildren(); + var movementData = collComponent && wireComponent + ? new GateMovementData { + Angle = math.radians(collComponent._angleMin), + AngleSpeed = 0, + ForcedMove = false, + IsOpen = false, + HitDirection = false + } : default; + + return new GateState( + collComponent ? gameObject.GetInstanceID() : 0, + wireComponent ? wireComponent.gameObject.GetInstanceID() : 0, + staticData, + movementData + ); + } + + #endregion + #region Editor Tooling public override ItemDataTransformType EditorPositionType => ItemDataTransformType.ThreeD; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementData.cs index c40586b53..a80d6abe0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct GateMovementData : IComponentData + internal struct GateMovementData { public float Angle; public float AngleSpeed; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs similarity index 58% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs index bb69b7e50..0a8d46773 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs @@ -1,39 +1,34 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using VisualPinball.Engine.VPT.Surface; - -namespace VisualPinball.Unity -{ - public class SurfaceBaker : ItemBaker - { - public override void Bake(SurfaceComponent authoring) - { - base.Bake(authoring); - - // physics collision data - var collComponent = GetComponentInChildren(); - if (collComponent) { - AddComponent(new LineSlingshotData { - IsDisabled = false, - Threshold = collComponent.SlingshotThreshold, - }); - } - - GetComponentInParent().RegisterSurface(authoring); - } - } -} +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal struct GateState + { + internal readonly int ItemId; + internal readonly int WireItemId; + internal GateStaticData Static; + internal GateMovementData Movement; + + public GateState(int itemId, int wireItemId, GateStaticData @static, GateMovementData movement) + { + ItemId = itemId; + WireItemId = wireItemId; + Static = @static; + Movement = movement; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs.meta new file mode 100644 index 000000000..08e2bb8a7 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: baf88e2f669140a6ae69edc71cb69619 +timeCreated: 1696494786 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticData.cs index 4eb9a0194..2c1cc728e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct GateStaticData : IComponentData + internal struct GateStaticData { public float AngleMin; public float AngleMax; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationData.cs index 71e320e64..c2dd115fb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct DropTargetAnimationData : IComponentData + internal struct DropTargetAnimationData { public const float DropTargetLimit = 52.0f; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs deleted file mode 100644 index 828a17450..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using VisualPinball.Engine.VPT.HitTarget; - -namespace VisualPinball.Unity -{ - public class DropTargetBaker : ItemBaker - { - public override void Bake(DropTargetComponent authoring) - { - base.Bake(authoring); - - var colliderComponent = GetComponent(); - var animationComponent = GetComponentInChildren(); - if (colliderComponent && animationComponent) { - - AddComponent(new DropTargetStaticData { - Speed = animationComponent.Speed, - RaiseDelay = animationComponent.RaiseDelay, - UseHitEvent = colliderComponent.UseHitEvent, - }); - - AddComponent(new DropTargetAnimationData { - IsDropped = animationComponent.IsDropped, - MoveDown = !animationComponent.IsDropped, - ZOffset = animationComponent.IsDropped ? -DropTargetAnimationData.DropTargetLimit : 0f - }); - } - - // register - GetComponentInParent().RegisterDropTarget(authoring); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs.meta deleted file mode 100644 index 66cb60131..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: a120608c3b854e1f9a5342886f77b6d3 -timeCreated: 1673023180 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs index 20f778cef..23b847ae7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs @@ -127,5 +127,49 @@ public override HitTargetData CopyDataTo(HitTargetData data, string[] materialNa } #endregion + + #region Runtime + + private void Awake() + { + // register at player + GetComponentInParent().RegisterDropTarget(this); + if (GetComponent() && GetComponentInChildren()) { + GetComponentInParent().Register(this); + } + } + + #endregion + + #region State + + internal DropTargetState CreateState() + { + var colliderComponent = GetComponent(); + var animationComponent = GetComponentInChildren(); + + var staticData = colliderComponent && animationComponent + ? new DropTargetStaticData { + Speed = animationComponent.Speed, + RaiseDelay = animationComponent.RaiseDelay, + UseHitEvent = colliderComponent.UseHitEvent, + } : default; + + var animationData = colliderComponent && animationComponent + ? new DropTargetAnimationData { + IsDropped = animationComponent.IsDropped, + MoveDown = !animationComponent.IsDropped, + ZOffset = animationComponent.IsDropped ? -DropTargetAnimationData.DropTargetLimit : 0f + } : default; + + return new DropTargetState( + colliderComponent && animationComponent ? gameObject.GetInstanceID() : 0, + animationComponent ? animationComponent.gameObject.GetInstanceID() : 0, + staticData, + animationData + ); + } + + #endregion } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs new file mode 100644 index 000000000..d4492dcde --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs @@ -0,0 +1,34 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal struct DropTargetState + { + internal readonly int ItemId; + internal readonly int AnimatedItemId; + internal DropTargetStaticData Static; + internal DropTargetAnimationData Animation; + + public DropTargetState(int itemId, int animatedItemId, DropTargetStaticData @static, DropTargetAnimationData animation) + { + ItemId = itemId; + AnimatedItemId = animatedItemId; + Static = @static; + Animation = animation; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs.meta new file mode 100644 index 000000000..0a6db4fdd --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e34f6f6716214c678cba4e902a46b810 +timeCreated: 1696495888 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticData.cs index 931feac11..dec0f2b8d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct DropTargetStaticData : IComponentData + internal struct DropTargetStaticData { public float Speed; public float RaiseDelay; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationData.cs index adf29abba..2f7e46ca9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct HitTargetAnimationData : IComponentData + internal struct HitTargetAnimationData { public float XRotation; public bool HitEvent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs deleted file mode 100644 index 1bd247a13..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using VisualPinball.Engine.VPT.HitTarget; - -namespace VisualPinball.Unity -{ - public class HitTargetBaker : ItemBaker - { - public override void Bake(HitTargetComponent authoring) - { - base.Bake(authoring); - - var hitTargetColliderComponent = GetComponent(); - var hitTargetAnimationComponent = GetComponentInChildren(); - if (hitTargetColliderComponent && hitTargetAnimationComponent) { - - AddComponent(new HitTargetStaticData { - Speed = hitTargetAnimationComponent.Speed, - MaxAngle = hitTargetAnimationComponent.MaxAngle, - }); - - AddComponent(new HitTargetAnimationData { - MoveDirection = true, - }); - } - - // register - GetComponentInParent().RegisterHitTarget(authoring); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs.meta deleted file mode 100644 index e4d69bb6b..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c0e158fb147149a88110ec2238763c1a -timeCreated: 1673023020 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs index 397559167..bf5e7b2a2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs @@ -107,5 +107,45 @@ public override HitTargetData CopyDataTo(HitTargetData data, string[] materialNa } #endregion + + #region Runtime + + private void Awake() + { + // register at player + GetComponentInParent().RegisterHitTarget(this); + if (GetComponent() && GetComponentInChildren()) { + GetComponentInParent().Register(this); + } + } + + #endregion + + #region State + + internal HitTargetState CreateState() + { + var hitTargetColliderComponent = GetComponent(); + var hitTargetAnimationComponent = GetComponentInChildren(); + var staticData = hitTargetColliderComponent && hitTargetAnimationComponent + ? new HitTargetStaticData { + Speed = hitTargetAnimationComponent.Speed, + MaxAngle = hitTargetAnimationComponent.MaxAngle, + } : default; + + var animationData = hitTargetColliderComponent && hitTargetAnimationComponent + ? new HitTargetAnimationData { + MoveDirection = true, + } : default; + + return new HitTargetState( + hitTargetColliderComponent && hitTargetAnimationComponent ? gameObject.GetInstanceID() : 0, + hitTargetAnimationComponent ? hitTargetAnimationComponent.gameObject.GetInstanceID() : 0, + staticData, + animationData + ); + } + + #endregion } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetState.cs new file mode 100644 index 000000000..5938e876f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetState.cs @@ -0,0 +1,34 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal struct HitTargetState + { + internal readonly int ItemId; + internal readonly int AnimatedItemId; + internal HitTargetStaticData Static; + internal HitTargetAnimationData Animation; + + public HitTargetState(int itemId, int animatedItemId, HitTargetStaticData @static, HitTargetAnimationData animation) + { + ItemId = itemId; + AnimatedItemId = animatedItemId; + Static = @static; + Animation = animation; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetState.cs.meta new file mode 100644 index 000000000..3d592f254 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a3893ee528fa4c5c8f3b0d8007999290 +timeCreated: 1696497154 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetStaticData.cs index 51553bf11..4e3e02271 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetStaticData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct HitTargetStaticData : IComponentData + internal struct HitTargetStaticData { public float Speed; public float MaxAngle; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs index 6ebea75b9..ab9d8ce75 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs @@ -257,6 +257,51 @@ public override void CopyFromObject(GameObject go) #endregion + #region State + + internal bool HasState => GetComponent(); + + internal KickerState CreateState() + { + // collision + var colliderComponent = GetComponent(); + var staticData = colliderComponent + ? new KickerStaticData { + Center = Position, + FallIn = colliderComponent.FallIn, + FallThrough = colliderComponent.FallThrough, + HitAccuracy = colliderComponent.HitAccuracy, + Scatter = colliderComponent.Scatter, + LegacyMode = true, // todo colliderComponent.LegacyMode, + ZLow = Surface?.Height(Position) ?? PlayfieldHeight + } : default; + + // if (!Data.LegacyMode) { + // // todo currently we don't allow non-legacy mode + // using (var blobBuilder = new BlobBuilder(Allocator.Temp)) { + // ref var blobAsset = ref blobBuilder.ConstructRoot(); + // var vertices = blobBuilder.Allocate(ref blobAsset.Vertices, Item.KickerHit.HitMesh.Length); + // var normals = blobBuilder.Allocate(ref blobAsset.Normals, Item.KickerHit.HitMesh.Length); + // for (var i = 0; i < Item.KickerHit.HitMesh.Length; i++) { + // var v = Item.KickerHit.HitMesh[i]; + // vertices[i] = new KickerMeshVertex { Vertex = v.ToUnityFloat3() }; + // normals[i] = new KickerMeshVertex { Vertex = new float3(KickerHitMesh.Vertices[i].Nx, KickerHitMesh.Vertices[i].Ny, KickerHitMesh.Vertices[i].Nz) }; + // } + // + // var blobAssetReference = blobBuilder.CreateBlobAssetReference(Allocator.Persistent); + // dstManager.AddComponentData(entity, new ColliderMeshData { Value = blobAssetReference }); + // } + // } + + return new KickerState( + colliderComponent ? colliderComponent.gameObject.GetInstanceID() : 0, + staticData, + new KickerCollisionData() + ); + } + + #endregion + #region Serialization public void OnBeforeSerialize() @@ -288,6 +333,12 @@ public void OnAfterDeserialize() private void Awake() { _originalRotationZ = Orientation; + + // register at player + GetComponentInParent().RegisterKicker(this); + if (GetComponent()) { + GetComponentInParent().Register(this); + } } private void Start() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs new file mode 100644 index 000000000..e9fcb4654 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs @@ -0,0 +1,32 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal struct KickerState + { + internal readonly int ItemId; + internal KickerStaticData Static; + internal KickerCollisionData Collision; + + public KickerState(int itemId, KickerStaticData @static, KickerCollisionData collision) + { + ItemId = itemId; + Static = @static; + Collision = collision; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs.meta new file mode 100644 index 000000000..556aeedca --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 26f155d768f3423c90752762fbb736a4 +timeCreated: 1696497627 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationData.cs index f4a9cd8c2..d37b9a74a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct PlungerAnimationData : IComponentData + internal struct PlungerAnimationData { public float Position; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs deleted file mode 100644 index a28210bd1..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs +++ /dev/null @@ -1,106 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Mathematics; -using VisualPinball.Engine.VPT; -using VisualPinball.Engine.VPT.Plunger; - -namespace VisualPinball.Unity -{ - public class PlungerBaker : ItemBaker - { - public override void Bake(PlungerComponent authoring) - { - base.Bake(authoring); - - var collComponent = GetComponent(); - if (!collComponent) { - // without collider, the plunger is only a dead mesh. - return; - } - - var zHeight = authoring.PositionZ; - var x = authoring.Position.x - authoring.Width; - var y = authoring.Position.y + authoring.Height; - var x2 = authoring.Position.x + authoring.Width; - - var frameTop = authoring.Position.y - collComponent.Stroke; - var frameBottom = authoring.Position.y; - var frameLen = frameBottom - frameTop; - var restPos = collComponent.ParkPosition; - var position = frameTop + restPos * frameLen; - - var info = new ColliderInfo { - ItemId = authoring.GetInstanceID(), - FireEvents = true, - IsEnabled = true, - ItemType = ItemType.Plunger, - }; - - AddComponent(new PlungerStaticData { - MomentumXfer = collComponent.MomentumXfer, - ScatterVelocity = collComponent.ScatterVelocity, - FrameStart = frameBottom, - FrameEnd = frameTop, - FrameLen = frameLen, - RestPosition = restPos, - IsAutoPlunger = collComponent.IsAutoPlunger, - IsMechPlunger = collComponent.IsMechPlunger, - SpeedFire = collComponent.SpeedFire, - NumFrames = (int)(collComponent.Stroke * (float)(PlungerMeshGenerator.PlungerFrameCount / 80.0f)) + 1, // 25 frames per 80 units travel - }); - - AddComponent(new PlungerColliderData { - LineSegSide0 = new LineCollider(new float2(x + 0.0001f, position), new float2(x, y), zHeight, zHeight + Plunger.PlungerHeight, info), - LineSegSide1 = new LineCollider(new float2(x2, y), new float2(x2 + 0.0001f, position), zHeight, zHeight + Plunger.PlungerHeight, info), - LineSegEnd = new LineCollider(new float2(x2, position), new float2(x, position), zHeight, zHeight + Plunger.PlungerHeight, info), - JointEnd0 = new LineZCollider(new float2(x, position), zHeight, zHeight + Plunger.PlungerHeight, info), - JointEnd1 = new LineZCollider(new float2(x2, position), zHeight, zHeight + Plunger.PlungerHeight, info), - }); - - AddComponent(new PlungerMovementData { - FireBounce = 0f, - Position = position, - RetractMotion = false, - ReverseImpulse = 0f, - Speed = 0f, - TravelLimit = frameTop, - FireSpeed = 0f, - FireTimer = 0 - }); - - AddComponent(new PlungerVelocityData { - Mech0 = 0f, - Mech1 = 0f, - Mech2 = 0f, - PullForce = 0f, - InitialSpeed = 0f, - AutoFireTimer = 0, - AddRetractMotion = false, - RetractWaitLoop = 0, - MechStrength = collComponent.MechStrength - }); - - AddComponent(new PlungerAnimationData { - Position = collComponent.ParkPosition - }); - - // register at player - GetComponentInParent().RegisterPlunger(authoring, authoring.analogPlungerAction); - - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs.meta deleted file mode 100644 index 2f3e32026..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 7ea09ece3265463c9ecdddb1b4e42893 -timeCreated: 1673024165 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderData.cs index eb2eb929e..77de61d0e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct PlungerColliderData : IComponentData + internal struct PlungerColliderData { public LineCollider LineSegSide0; public LineCollider LineSegSide1; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs index 6f25815a5..ff3acb095 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs @@ -20,7 +20,6 @@ using System; using System.Collections.Generic; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using UnityEngine.InputSystem; @@ -73,6 +72,19 @@ public class PlungerComponent : MainRenderableComponent, #endregion + #region Runtime + + private void Awake() + { + // register at player + GetComponentInParent().RegisterPlunger(this, analogPlungerAction); + if (GetComponent()) { + GetComponentInParent().Register(this); + } + } + + #endregion + #region Wiring public IEnumerable AvailableCoils => new[] { @@ -258,6 +270,84 @@ public override void CopyFromObject(GameObject go) #endregion + #region State + + internal PlungerState CreateState() + { + var collComponent = GetComponent(); + if (!collComponent) { + // without collider, the plunger is only a dead mesh. + return default; + } + + var zHeight = PositionZ; + var x = Position.x - Width; + var y = Position.y + Height; + var x2 = Position.x + Width; + + var frameTop = Position.y - collComponent.Stroke; + var frameBottom = Position.y; + var frameLen = frameBottom - frameTop; + var restPos = collComponent.ParkPosition; + var position = frameTop + restPos * frameLen; + + var info = new ColliderInfo { + ItemId = GetInstanceID(), + FireEvents = true, + IsEnabled = true, + ItemType = ItemType.Plunger, + }; + + return new PlungerState( + gameObject.GetInstanceID(), + new PlungerStaticData { + MomentumXfer = collComponent.MomentumXfer, + ScatterVelocity = collComponent.ScatterVelocity, + FrameStart = frameBottom, + FrameEnd = frameTop, + FrameLen = frameLen, + RestPosition = restPos, + IsAutoPlunger = collComponent.IsAutoPlunger, + IsMechPlunger = collComponent.IsMechPlunger, + SpeedFire = collComponent.SpeedFire, + NumFrames = (int)(collComponent.Stroke * (float)(PlungerMeshGenerator.PlungerFrameCount / 80.0f)) + 1, // 25 frames per 80 units travel + }, + new PlungerColliderData { + LineSegSide0 = new LineCollider(new float2(x + 0.0001f, position), new float2(x, y), zHeight, zHeight + Plunger.PlungerHeight, info), + LineSegSide1 = new LineCollider(new float2(x2, y), new float2(x2 + 0.0001f, position), zHeight, zHeight + Plunger.PlungerHeight, info), + LineSegEnd = new LineCollider(new float2(x2, position), new float2(x, position), zHeight, zHeight + Plunger.PlungerHeight, info), + JointEnd0 = new LineZCollider(new float2(x, position), zHeight, zHeight + Plunger.PlungerHeight, info), + JointEnd1 = new LineZCollider(new float2(x2, position), zHeight, zHeight + Plunger.PlungerHeight, info), + }, + new PlungerMovementData { + FireBounce = 0f, + Position = position, + RetractMotion = false, + ReverseImpulse = 0f, + Speed = 0f, + TravelLimit = frameTop, + FireSpeed = 0f, + FireTimer = 0 + }, + new PlungerVelocityData { + Mech0 = 0f, + Mech1 = 0f, + Mech2 = 0f, + PullForce = 0f, + InitialSpeed = 0f, + AutoFireTimer = 0, + AddRetractMotion = false, + RetractWaitLoop = 0, + MechStrength = collComponent.MechStrength + }, + new PlungerAnimationData { + Position = collComponent.ParkPosition + } + ); + } + + #endregion + public void UpdateParkPosition(float pos) { foreach (var skinnedMeshRenderer in GetComponentsInChildren()) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementData.cs index 436cfdd57..419db76ca 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct PlungerMovementData : IComponentData + internal struct PlungerMovementData { /// /// Current rod speed, in table distance units per second(?) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs new file mode 100644 index 000000000..e0d3f91e6 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs @@ -0,0 +1,38 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal struct PlungerState + { + internal readonly int ItemId; + internal PlungerStaticData Static; + internal PlungerColliderData Collider; + internal PlungerMovementData Movement; + internal PlungerVelocityData Velocity; + internal PlungerAnimationData Animation; + + public PlungerState(int itemId, PlungerStaticData @static, PlungerColliderData collider, PlungerMovementData movement, PlungerVelocityData velocity, PlungerAnimationData animation) + { + ItemId = itemId; + Static = @static; + Collider = collider; + Movement = movement; + Velocity = velocity; + Animation = animation; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs.meta new file mode 100644 index 000000000..aeb86b8fa --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: be12823300e24d0e97f4e9beb8608143 +timeCreated: 1696499320 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticData.cs index e7fc3d150..c18030e69 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct PlungerStaticData : IComponentData + internal struct PlungerStaticData { // collision public float MomentumXfer; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityData.cs index e7c1fc5dc..f429bbb60 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct PlungerVelocityData : IComponentData + internal struct PlungerVelocityData { /// /// Recent history of mechanical plunger readings. We keep the diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs deleted file mode 100644 index ef596e9b0..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Mathematics; -using VisualPinball.Engine.Common; -using VisualPinball.Engine.VPT.Spinner; - -namespace VisualPinball.Unity -{ - public class SpinnerBaker : ItemBaker - { - public override void Bake(SpinnerComponent authoring) - { - base.Bake(authoring); - - // physics collision data - var collComponent = GetComponent(); - if (collComponent) { - - AddComponent(new SpinnerStaticData { - AngleMax = math.radians(authoring.AngleMax), - AngleMin = math.radians(authoring.AngleMin), - Damping = math.pow(authoring.Damping, (float)PhysicsConstants.PhysFactor), - Elasticity = collComponent.Elasticity, - Height = authoring.Height - }); - } - - // animation - if (GetComponentInChildren()) { - AddComponent(new SpinnerMovementData { - Angle = math.radians(math.clamp(0.0f, authoring.AngleMin, authoring.AngleMax)), - AngleSpeed = 0f - }); - } - - // register - GetComponentInParent().RegisterSpinner(authoring); - - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs.meta deleted file mode 100644 index 62eca60a0..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 860488c7d3274f9a82879a98ed9fd679 -timeCreated: 1673104612 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs index aa868e31a..7119555a7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs @@ -23,7 +23,9 @@ using System; using System.Collections.Generic; +using Unity.Mathematics; using UnityEngine; +using VisualPinball.Engine.Common; using VisualPinball.Engine.Game.Engines; using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.Spinner; @@ -88,6 +90,17 @@ public class SpinnerComponent : MainRenderableComponent, #endregion + #region Runtime + + private void Awake() + { + // register at player + GetComponentInParent().RegisterSpinner(this); + GetComponentInParent().Register(this); + } + + #endregion + #region Wiring public IEnumerable AvailableSwitches => new[] { @@ -231,6 +244,39 @@ public override void CopyFromObject(GameObject go) #endregion + #region State + + internal SpinnerState CreateState() + { + // physics collision data + var collComponent = GetComponent(); + var staticData = collComponent + ? new SpinnerStaticData { + AngleMax = math.radians(AngleMax), + AngleMin = math.radians(AngleMin), + Damping = math.pow(Damping, (float)PhysicsConstants.PhysFactor), + Elasticity = collComponent.Elasticity, + Height = Height + } : default; + + // animation + var animComponent = GetComponentInChildren(); + var movementData = animComponent + ? new SpinnerMovementData { + Angle = math.radians(math.clamp(0.0f, AngleMin, AngleMax)), + AngleSpeed = 0f + } : default; + + return new SpinnerState( + collComponent ? gameObject.GetInstanceID() : 0, + animComponent ? animComponent.gameObject.GetInstanceID() : 0, + staticData, + movementData + ); + } + + #endregion + #region Editor Tooling public override ItemDataTransformType EditorPositionType => ItemDataTransformType.ThreeD; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementData.cs index 469e48ee3..1e55b46e6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct SpinnerMovementData : IComponentData + internal struct SpinnerMovementData { public float Angle; public float AngleSpeed; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs new file mode 100644 index 000000000..21a642161 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs @@ -0,0 +1,34 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal struct SpinnerState + { + internal readonly int ItemId; + internal readonly int AnimationItemId; + internal SpinnerStaticData Static; + internal SpinnerMovementData Movement; + + public SpinnerState(int itemId, int animationItemId, SpinnerStaticData @static, SpinnerMovementData movement) + { + ItemId = itemId; + AnimationItemId = animationItemId; + Static = @static; + Movement = movement; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs.meta new file mode 100644 index 000000000..da6c1b01d --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 50805e48005345e69c19a503e93d1a59 +timeCreated: 1696500242 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticData.cs index 87b7c0b06..595b5c404 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct SpinnerStaticData : IComponentData + internal struct SpinnerStaticData { public float AngleMin; public float AngleMax; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs.meta deleted file mode 100644 index 461ba4b2f..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ae5c95fc5fad42a693994927811e8acf -timeCreated: 1673104974 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs index d2db0bb58..73e744003 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs @@ -64,6 +64,19 @@ public class SurfaceComponent : MainRenderableComponent, ISurfaceCo #endregion + #region Runtime + + private void Awake() + { + // register at player + GetComponentInParent().RegisterSurface(this); + if (GetComponentInChildren()) { + GetComponentInParent().Register(this); + } + } + + #endregion + #region Transformation public float Height(Vector2 _) => HeightTop + PlayfieldHeight; @@ -191,6 +204,24 @@ public override void CopyFromObject(GameObject go) #endregion + #region State + + internal SurfaceState CreateState() + { + // physics collision data + var collComponent = GetComponentInChildren(); + if (!collComponent) { + return default; + } + + return new SurfaceState(gameObject.GetInstanceID(), new LineSlingshotData { + IsDisabled = false, + Threshold = collComponent.SlingshotThreshold, + }); + } + + #endregion + #region Editor Tooling private Vector3 DragPointCenter { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs new file mode 100644 index 000000000..5150c1b2a --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs @@ -0,0 +1,30 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal struct SurfaceState + { + internal readonly int ItemId; + internal LineSlingshotData Slingshot; + + public SurfaceState(int itemId, LineSlingshotData slingshot) + { + ItemId = itemId; + Slingshot = slingshot; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs.meta new file mode 100644 index 000000000..a93163541 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: faab83ea51c34c6991cfeb4c1540bd2d +timeCreated: 1696503371 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationData.cs index 86cc7cc23..c6207ebf2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct TriggerAnimationData : IComponentData + internal struct TriggerAnimationData { public bool HitEvent; public bool UnHitEvent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs deleted file mode 100644 index 68b126239..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using VisualPinball.Engine.VPT.Trigger; - -namespace VisualPinball.Unity -{ - public class TriggerBaker : ItemBaker - { - public override void Bake(TriggerComponent authoring) - { - base.Bake(authoring); - - var collComponent = GetComponentInChildren(); - var animComponent = GetComponentInChildren(); - var meshComponent = GetComponentInChildren(); - if (collComponent && animComponent && meshComponent) { - AddComponent(new TriggerAnimationData()); - AddComponent(new TriggerMovementData()); - AddComponent(new TriggerStaticData { - AnimSpeed = animComponent.AnimSpeed, - Radius = collComponent.HitCircleRadius, - Shape = meshComponent.Shape, - TableScaleZ = 1f - }); - } - - // register - GetComponentInParent().RegisterTrigger(authoring); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs.meta deleted file mode 100644 index 848c4a174..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 6c66eb4fd3594e32bf152aa3fbd6d3f6 -timeCreated: 1673105180 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs index 5a32a3318..896b4702d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs @@ -79,6 +79,20 @@ public class TriggerComponent : MainRenderableComponent, #endregion + #region Runtime + + private void Awake() + { + // register at player + GetComponentInParent().RegisterTrigger(this); + + if (GetComponentInChildren() && GetComponentInChildren() && GetComponentInChildren()) { + GetComponentInParent().Register(this); + } + } + + #endregion + #region Wiring public IEnumerable AvailableSwitches => new[] { @@ -232,6 +246,29 @@ public override void CopyFromObject(GameObject go) #endregion + #region State + + internal TriggerState CreateState() + { + var collComponent = GetComponentInChildren(); + var animComponent = GetComponentInChildren(); + var meshComponent = GetComponentInChildren(); + return new TriggerState( + gameObject.GetInstanceID(), + animComponent ? animComponent.gameObject.GetInstanceID() : 0, + new TriggerStaticData { + AnimSpeed = animComponent.AnimSpeed, + Radius = collComponent.HitCircleRadius, + Shape = meshComponent.Shape, + TableScaleZ = 1f + }, + new TriggerMovementData(), + new TriggerAnimationData() + ); + } + + #endregion + #region Editor Tooling public override ItemDataTransformType EditorPositionType => ItemDataTransformType.TwoD; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementData.cs index 9465563ed..472a5e5e8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct TriggerMovementData : IComponentData + internal struct TriggerMovementData { public float HeightOffset; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs new file mode 100644 index 000000000..fd1a93c9f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs @@ -0,0 +1,36 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace VisualPinball.Unity +{ + internal struct TriggerState + { + internal readonly int ItemId; + internal readonly int AnimatedItemId; + internal TriggerStaticData Static; + internal TriggerMovementData Movement; + internal TriggerAnimationData Animation; + + public TriggerState(int itemId, int animatedItemId, TriggerStaticData @static, TriggerMovementData movement, TriggerAnimationData animation) + { + ItemId = itemId; + AnimatedItemId = animatedItemId; + Static = @static; + Movement = movement; + Animation = animation; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs.meta new file mode 100644 index 000000000..e79ca9be8 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 97a2cfead66f4bda83aa41e7848ba7aa +timeCreated: 1696503613 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticData.cs index 21ae12150..2c9342a36 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct TriggerStaticData : IComponentData + internal struct TriggerStaticData { public int Shape; public float Radius; From a5adfd0d5661e381199197eed325ce6a01ce8a92 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 5 Oct 2023 21:06:26 +0200 Subject: [PATCH 062/159] jobs: Add narrow phase to remaining items. --- .../Game/PhysicsColliderExtensions.cs | 45 ++++++++++ .../VisualPinball.Unity/Game/PhysicsEngine.cs | 32 ++++++- .../VisualPinball.Unity/Game/PhysicsState.cs | 42 ++++++++- .../Game/PhysicsStaticNarrowPhase.cs | 8 +- .../Physics/Collider/Collider.cs | 6 +- .../Physics/Collider/ColliderRef.cs | 86 ++++++++++++++----- .../Physics/Collider/LineCollider.cs | 16 ++-- .../Physics/Collider/LineSlingshotCollider.cs | 8 +- .../Collision/StaticNarrowPhaseSystem.cs | 62 ++++++------- .../VPT/Gate/GateCollider.cs | 6 +- .../VPT/Plunger/PlungerCollider.cs | 10 +-- .../VPT/Spinner/SpinnerCollider.cs | 6 +- 12 files changed, 237 insertions(+), 90 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs index a46f39cad..5028f0f4e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs @@ -51,6 +51,24 @@ internal static unsafe ref PlaneCollider GetPlaneCollider(this in BlobAssetRefer } } + internal static unsafe ref SpinnerCollider GetSpinnerCollider(this in BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var spinnerCollider = (SpinnerCollider*) cPtr; + return ref UnsafeUtility.AsRef(spinnerCollider); + } + } + + internal static unsafe ref GateCollider GetGateCollider(this in BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var gateCollider = (GateCollider*) cPtr; + return ref UnsafeUtility.AsRef(gateCollider); + } + } + internal static unsafe ref LineCollider GetLineCollider(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; @@ -78,6 +96,15 @@ internal static unsafe ref Line3DCollider GetLine3DCollider(this in BlobAssetRef } } + internal static unsafe ref LineSlingshotCollider GetLineSlingshotCollider(this in BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var lineSlingshotCollider = (LineSlingshotCollider*) cPtr; + return ref UnsafeUtility.AsRef(lineSlingshotCollider); + } + } + internal static unsafe ref PointCollider GetPointCollider(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; @@ -87,6 +114,15 @@ internal static unsafe ref PointCollider GetPointCollider(this in BlobAssetRefer } } + internal static unsafe ref LineZCollider GetLineZCollider(this in BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var lineZCollider = (LineZCollider*) cPtr; + return ref UnsafeUtility.AsRef(lineZCollider); + } + } + internal static unsafe ref FlipperCollider GetFlipperCollider(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; @@ -95,5 +131,14 @@ internal static unsafe ref FlipperCollider GetFlipperCollider(this in BlobAssetR return ref UnsafeUtility.AsRef(flipperCollider); } } + + internal static unsafe ref PlungerCollider GetPlungerCollider(this in BlobAssetReference colliders, int index) + { + ref var coll = ref colliders.Value.Colliders[index].Value; + fixed (Collider* cPtr = &coll) { + var plungerCollider = (PlungerCollider*) cPtr; + return ref UnsafeUtility.AsRef(plungerCollider); + } + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 6a0393951..fbc8add11 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -61,6 +61,10 @@ internal void Register(T item) where T : MonoBehaviour { var go = item.gameObject; var itemId = go.GetInstanceID(); + if (_transforms.ContainsKey(itemId)) { + // animation components are always added, sometimes they overlap with the main component (i.e. triggers) + return; + } _transforms.Add(itemId, go.transform); switch (item) { @@ -151,12 +155,22 @@ private void Update() InsideOfs = _insideOfs, Events = events, Balls = _balls, - FlipperStates = _flipperStates, BumperStates = _bumperStates, + DropTargetStates = _dropTargetStates, + FlipperStates = _flipperStates, + GateStates = _gateStates, + HitTargetStates = _hitTargetStates, + KickerStates = _kickerStates, + PlungerStates = _plungerStates, + SpinnerStates = _spinnerStates, + SurfaceStates = _surfaceStates, }; var env = _physicsEnv[0]; - var state = new PhysicsState(ref env, ref _octree, ref _colliders, ref events, ref _insideOfs, ref _balls, ref _flipperStates, ref _bumperStates); + var state = new PhysicsState(ref env, ref _octree, ref _colliders, ref events, ref _insideOfs, ref _balls, + ref _bumperStates, ref _dropTargetStates, ref _flipperStates, ref _gateStates, + ref _hitTargetStates, ref _kickerStates, ref _plungerStates, ref _spinnerStates, + ref _surfaceStates); // process input while (_inputActions.Count > 0) { @@ -247,13 +261,23 @@ internal struct UpdatePhysicsJob : IJob public NativeQueue.ParallelWriter Events; public NativeParallelHashMap Balls; - public NativeParallelHashMap FlipperStates; public NativeParallelHashMap BumperStates; + public NativeParallelHashMap DropTargetStates; + public NativeParallelHashMap FlipperStates; + public NativeParallelHashMap GateStates; + public NativeParallelHashMap HitTargetStates; + public NativeParallelHashMap KickerStates; + public NativeParallelHashMap PlungerStates; + public NativeParallelHashMap SpinnerStates; + public NativeParallelHashMap SurfaceStates; public void Execute() { var env = PhysicsEnv[0]; - var state = new PhysicsState(ref env, ref Octree, ref Colliders, ref Events, ref InsideOfs, ref Balls, ref FlipperStates, ref BumperStates); + var state = new PhysicsState(ref env, ref Octree, ref Colliders, ref Events, ref InsideOfs, ref Balls, + ref BumperStates, ref DropTargetStates, ref FlipperStates, ref GateStates, + ref HitTargetStates, ref KickerStates, ref PlungerStates, ref SpinnerStates, + ref SurfaceStates); var cycle = new PhysicsCycle(Allocator.Temp); while (env.CurPhysicsFrameTime < InitialTimeUsec) // loop here until current (real) time matches the physics (simulated) time diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index d2042c6cc..f1d4a8eeb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -30,12 +30,23 @@ internal struct PhysicsState internal NativeQueue.ParallelWriter EventQueue; internal InsideOfs InsideOfs; internal NativeParallelHashMap Balls; - internal NativeParallelHashMap FlipperStates; internal NativeParallelHashMap BumperStates; + internal NativeParallelHashMap DropTargetStates; + internal NativeParallelHashMap FlipperStates; + internal NativeParallelHashMap GateStates; + internal NativeParallelHashMap HitTargetStates; + internal NativeParallelHashMap KickerStates; + internal NativeParallelHashMap PlungerStates; + internal NativeParallelHashMap SpinnerStates; + internal NativeParallelHashMap SurfaceStates; public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAssetReference colliders, ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeParallelHashMap balls, - ref NativeParallelHashMap flipperStates, ref NativeParallelHashMap bumperStates) + ref NativeParallelHashMap bumperStates, ref NativeParallelHashMap dropTargetStates, + ref NativeParallelHashMap flipperStates, ref NativeParallelHashMap gateStates, + ref NativeParallelHashMap hitTargetStates, ref NativeParallelHashMap kickerStates, + ref NativeParallelHashMap plungerStates, ref NativeParallelHashMap spinnerStates, + ref NativeParallelHashMap surfaceStates) { Env = env; Octree = octree; @@ -43,8 +54,15 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs EventQueue = eventQueue; InsideOfs = insideOfs; Balls = balls; - FlipperStates = flipperStates; BumperStates = bumperStates; + DropTargetStates = dropTargetStates; + FlipperStates = flipperStates; + GateStates = gateStates; + HitTargetStates = hitTargetStates; + KickerStates = kickerStates; + PlungerStates = plungerStates; + SpinnerStates = spinnerStates; + SurfaceStates = surfaceStates; } internal Collider GetCollider(int colliderId) => Colliders.Value.Colliders[colliderId].Value; @@ -55,6 +73,24 @@ internal ref FlipperState GetFlipperState(int colliderId) return ref FlipperStates.GetValueByRef(collider.ItemId); } + internal ref PlungerState GetPlungerState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return ref PlungerStates.GetValueByRef(collider.ItemId); + } + + internal bool HasDropTargetState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return DropTargetStates.ContainsKey(collider.ItemId); + } + + internal ref DropTargetState GetDropTargetState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return ref DropTargetStates.GetValueByRef(collider.ItemId); + } + internal ref BumperState GetBumperState(int colliderId) { var collider = Colliders.Value.Colliders[colliderId].Value; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index 7060e64fa..a12626995 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -37,8 +37,8 @@ ref PhysicsState state var newCollEvent = new CollisionEventData(); var colliderRef = new ColliderRef(overlappingColliders[i], ref state.Colliders); var newTime = colliderRef.HitTest(ref ball, ref newCollEvent, ref contacts, ref state); - SaveCollisions(ref ball, ref newCollEvent, ref contacts, colliderRef.Id, newTime); - } + SaveCollisions(ref ball, ref newCollEvent, ref contacts, colliderRef.Id, newTime); + } // no negative time allowed if (ball.CollisionEvent.HitTime < 0) { @@ -59,10 +59,10 @@ private static void SaveCollisions(ref BallData ball, ref CollisionEventData new { var validHit = newTime >= 0f && !Math.Sign(newTime) && newTime <= ball.CollisionEvent.HitTime; - if (newCollEvent.IsContact || validHit) { + if (newCollEvent.IsContact || validHit) { // todo why newCollEvent.IsContact? it's not in vpx source newCollEvent.SetCollider(colliderId, ball.Id); newCollEvent.HitTime = newTime; - if (newCollEvent.IsContact) { + if (newCollEvent.IsContact) { // remember all contacts? contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); } else { // if (validhit) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 9061d040e..6175f65b8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -96,11 +96,11 @@ internal static unsafe float HitTest(ref Collider coll, ref CollisionEventData c case ColliderType.Line: // return ((LineCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); case ColliderType.LineZ: - return ((LineZCollider*) collider)->HitTest(ref collEvent, in ball, dTime); + // return ((LineZCollider*) collider)->HitTest(ref collEvent, in ball, dTime); case ColliderType.Line3D: - return ((Line3DCollider*) collider)->HitTest(ref collEvent, in ball, dTime); + // return ((Line3DCollider*) collider)->HitTest(ref collEvent, in ball, dTime); case ColliderType.Point: - return ((PointCollider*) collider)->HitTest(ref collEvent, in ball, dTime); + // return ((PointCollider*) collider)->HitTest(ref collEvent, in ball, dTime); case ColliderType.Plane: return ((PlaneCollider*) collider)->HitTest(ref collEvent, in ball, dTime); case ColliderType.Spinner: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs index 10b847ae6..d1b9fa5ac 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs @@ -16,6 +16,7 @@ using Unity.Collections; using Unity.Entities; +using VisualPinball.Engine.VPT; namespace VisualPinball.Unity { @@ -32,37 +33,78 @@ internal ColliderRef(int id, ref BlobAssetReference colliders) internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref NativeList contacts, ref PhysicsState state) { - var hitTime = -1f; + if (IsInactiveDropTarget(ref state)) { + return -1f; + } switch (_colliders.GetType(Id)) { case ColliderType.Bumper: case ColliderType.Circle: - hitTime = _colliders.GetCircleCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); - break; - case ColliderType.Plane: - hitTime = _colliders.GetPlaneCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); - break; + return _colliders.GetCircleCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime); + + case ColliderType.Gate: + return _colliders.GetGateCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime); + case ColliderType.Line: - hitTime = _colliders.GetLineCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, ref ball, ball.CollisionEvent.HitTime); - break; - case ColliderType.Triangle: - hitTime = _colliders.GetTriangleCollider(Id).HitTest(ref collEvent, in state.InsideOfs, in ball, ball.CollisionEvent.HitTime); - break; + return _colliders.GetLineCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime); + + case ColliderType.LineZ: + return _colliders.GetLineZCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + case ColliderType.Line3D: - hitTime = _colliders.GetLine3DCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); - break; + return _colliders.GetLine3DCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + + case ColliderType.LineSlingShot: + return _colliders.GetLineSlingshotCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); + case ColliderType.Point: - hitTime = _colliders.GetPointCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); - break; + return _colliders.GetPointCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + + case ColliderType.Plane: + return _colliders.GetPlaneCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + + case ColliderType.Spinner: + return _colliders.GetSpinnerCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime); + + case ColliderType.Triangle: + return _colliders.GetTriangleCollider(Id).HitTest(ref collEvent, in state.InsideOfs, in ball, + ball.CollisionEvent.HitTime); + + case ColliderType.KickerCircle: + case ColliderType.TriggerCircle: + return _colliders.GetCircleCollider(Id).HitTestBasicRadius(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime, false, false, false); + + case ColliderType.TriggerLine: + return _colliders.GetLineCollider(Id).HitTestBasic(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime, false, false, false); + case ColliderType.Flipper: ref var flipperState = ref state.GetFlipperState(Id); - hitTime = _colliders.GetFlipperCollider(Id).HitTest( - ref collEvent, ref state.InsideOfs, ref flipperState.Hit, - in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, - in ball, collEvent.HitTime - ); - break; + return _colliders.GetFlipperCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, ref flipperState.Hit, + in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, in ball, collEvent.HitTime); + + case ColliderType.Plunger: + ref var plungerState = ref state.GetPlungerState(Id); + return _colliders.GetPlungerCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, ref plungerState.Movement, + in plungerState.Collider, in plungerState.Static, in ball, collEvent.HitTime); + } + return -1f; + } + + private bool IsInactiveDropTarget(ref PhysicsState state) + { + ref var coll = ref _colliders.Value.Colliders[Id].Value; + if (coll.ItemType == ItemType.HitTarget && state.HasDropTargetState(Id)) { + ref var dropTargetState = ref state.GetDropTargetState(Id); + if (dropTargetState.Animation.IsDropped || dropTargetState.Animation.MoveAnimation) { // QUICKFIX so that DT is not triggered twice + return true; + } } - return hitTime; + return false; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index ebfab2b4e..5a5ad4138 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -39,7 +39,7 @@ internal struct LineCollider : ICollider public readonly float ZHigh; private float _length; - private ItemType ItemType => _header.ItemType; + internal ItemType ItemType => _header.ItemType; private int ItemId => _header.ItemId; public float V1y { set => V1.y = value; } @@ -92,24 +92,24 @@ public void CalcNormal() #region Narrowphase public static float HitTest(ref CollisionEventData collEvent, - ref InsideOfs insideOfs, in LineCollider coll, ref BallData ball, float dTime) + ref InsideOfs insideOfs, in LineCollider coll, in BallData ball, float dTime) { - return HitTestBasic(ref collEvent, ref insideOfs, in coll, ref ball, dTime, true, true, true); // normal face, lateral, rigid + return HitTestBasic(ref collEvent, ref insideOfs, in coll, in ball, dTime, true, true, true); // normal face, lateral, rigid } public float HitTest(ref CollisionEventData collEvent, - ref InsideOfs insideOfs, ref BallData ball, float dTime) + ref InsideOfs insideOfs, in BallData ball, float dTime) { - return HitTestBasic(ref collEvent, ref insideOfs, in this, ref ball, dTime, true, true, true); // normal face, lateral, rigid + return HitTestBasic(ref collEvent, ref insideOfs, in this, in ball, dTime, true, true, true); // normal face, lateral, rigid } - public float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs insideOfs, ref BallData ball, float dTime, + public float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallData ball, float dTime, bool direction, bool lateral, bool rigid) { - return HitTestBasic(ref collEvent, ref insideOfs, in this, ref ball, dTime, direction, lateral, rigid); + return HitTestBasic(ref collEvent, ref insideOfs, in this, in ball, dTime, direction, lateral, rigid); } - public static float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in LineCollider coll, ref BallData ball, float dTime, bool direction, bool lateral, bool rigid) + public static float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in LineCollider coll, in BallData ball, float dTime, bool direction, bool lateral, bool rigid) { // ball velocity var ballVx = ball.Velocity.x; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs index 33f6f5444..c4678ec4d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs @@ -83,15 +83,15 @@ private void CalcNormal() #region Narrowphase - public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, ref BallData ball, float dTime) + public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallData ball, float dTime) { - return HitTest(ref collEvent, ref this, ref insideOfs, ref ball, dTime); + return HitTest(ref collEvent, ref this, ref insideOfs, in ball, dTime); } - private static float HitTest(ref CollisionEventData collEvent, ref LineSlingshotCollider coll, ref InsideOfs insideOfs, ref BallData ball, float dTime) + private static float HitTest(ref CollisionEventData collEvent, ref LineSlingshotCollider coll, ref InsideOfs insideOfs, in BallData ball, float dTime) { ref var lineColl = ref UnsafeUtility.As(ref coll); - return LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in lineColl, ref ball, dTime, true, true, true); + return LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in lineColl, in ball, dTime, true, true, true); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs index 5c6bb151d..798cb9718 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs @@ -116,20 +116,20 @@ protected override void OnUpdate() break; case ColliderType.Plunger: - if (HasComponent(coll.ItemId) && - HasComponent(coll.ItemId) && - HasComponent(coll.ItemId)) - { - var plungerColliderData = GetComponent(coll.ItemId); - var plungerStaticData = GetComponent(coll.ItemId); - var plungerMovementData = GetComponent(coll.ItemId); - // newTime = ((PlungerCollider*)collider)->HitTest( - // ref newCollEvent, ref insideOfs, ref plungerMovementData, - // in plungerColliderData, in plungerStaticData, in ballData, collEvent.HitTime - // ); - - SetComponent(coll.ItemId, plungerMovementData); - } + // if (HasComponent(coll.ItemId) && + // HasComponent(coll.ItemId) && + // HasComponent(coll.ItemId)) + // { + // var plungerColliderData = GetComponent(coll.ItemId); + // var plungerStaticData = GetComponent(coll.ItemId); + // var plungerMovementData = GetComponent(coll.ItemId); + // // newTime = ((PlungerCollider*)collider)->HitTest( + // // ref newCollEvent, ref insideOfs, ref plungerMovementData, + // // in plungerColliderData, in plungerStaticData, in ballData, collEvent.HitTime + // // ); + // + // SetComponent(coll.ItemId, plungerMovementData); + // } break; case ColliderType.Line: case ColliderType.Line3D: @@ -138,23 +138,23 @@ protected override void OnUpdate() case ColliderType.Plane: case ColliderType.Point: case ColliderType.Triangle: - // hit target - if (coll.Header.ItemType == ItemType.HitTarget) { - if (HasComponent(coll.ItemId)) { - var dropTargetAnimationData = GetComponent(coll.ItemId); - if (dropTargetAnimationData.IsDropped || dropTargetAnimationData.MoveAnimation) { // QUICKFIX so that DT is not triggered twice - saveCollision = false; - } - else { - newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); - } - } - if (HasComponent(coll.ItemId)) { - newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); - } - } - else - newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); + // // hit target + // if (coll.Header.ItemType == ItemType.HitTarget) { + // if (HasComponent(coll.ItemId)) { + // var dropTargetAnimationData = GetComponent(coll.ItemId); + // if (dropTargetAnimationData.IsDropped || dropTargetAnimationData.MoveAnimation) { // QUICKFIX so that DT is not triggered twice + // saveCollision = false; + // } + // else { + // newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); + // } + // } + // if (HasComponent(coll.ItemId)) { + // newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); + // } + // } + // else + // newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); break; default: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs index cd1a6d4f3..f621de0bf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs @@ -58,21 +58,21 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray= 0) { // signal the Collide() function that the hit is on the front or back side collEvent.HitFlag = false; return hitTime; } - hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg1, ref ball, dTime, false, true, false); // any face, lateral, non-rigid + hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg1, in ball, dTime, false, true, false); // any face, lateral, non-rigid if (hitTime >= 0) { collEvent.HitFlag = true; return hitTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs index acdd53139..b9bd895ba 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs @@ -78,7 +78,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray= 0.0f) { // signal the Collide() function that the hit is on the front or back side collEvent.HitFlag = true; return hitTime; } - hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg1, ref ball, dTime, false, true, false); // any face, lateral, non-rigid + hitTime = LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in LineSeg1, in ball, dTime, false, true, false); // any face, lateral, non-rigid if (hitTime >= 0.0f) { // signal the Collide() function that the hit is on the front or back side collEvent.HitFlag = false; From d3eba6f94b01e1832859edc98e2a18e5c7a8e864 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 5 Oct 2023 23:16:46 +0200 Subject: [PATCH 063/159] jobs: Add collision to remaining items. --- .../Collections/CollectionExtensions.cs | 5 + .../VisualPinball.Unity/Game/PhysicsEngine.cs | 8 +- .../VisualPinball.Unity/Game/PhysicsState.cs | 47 +++- .../Game/PhysicsStaticCollision.cs | 139 ++++++++++-- .../Physics/Collider/Collider.cs | 4 +- .../Physics/Collider/Line3DCollider.cs | 2 +- .../Physics/Collider/LineCollider.cs | 2 +- .../Physics/Collider/LineSlingshotCollider.cs | 4 +- .../Physics/Collider/LineZCollider.cs | 2 +- .../Physics/Collider/PointCollider.cs | 2 +- .../Physics/Collider/TriangleCollider.cs | 2 +- .../Collision/StaticCollisionSystem.cs | 208 +++++++++--------- .../VPT/Gate/GateCollider.cs | 4 +- .../VPT/HitTarget/TargetCollider.cs | 9 +- .../VPT/Kicker/KickerCollider.cs | 22 +- .../VPT/Kicker/KickerColliderMeshData.cs | 34 ++- .../VPT/Kicker/KickerComponent.cs | 27 +-- .../VPT/Kicker/KickerState.cs | 4 +- 18 files changed, 350 insertions(+), 175 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs index cb5d7feb0..4070c8752 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/CollectionExtensions.cs @@ -85,6 +85,11 @@ private static ref TValue GetValueByRef(this ref UnsafeParallelHas #region Own stuff + public static ref T GetElementAsRef(this NativeArray array, int index) where T : unmanaged + { + return ref UnsafeUtility.ArrayElementAsRef(array.GetUnsafePtr(), index); + } + public static ref T GetElementAsRef(this NativeList list, int index) where T : unmanaged { return ref UnsafeUtility.ArrayElementAsRef(list.GetUnsafePtr(), index); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index fbc8add11..a70923cef 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -49,6 +49,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeParallelHashMap _plungerStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _spinnerStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _surfaceStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashMap _triggerStates = new(0, Allocator.Persistent); [NonSerialized] private readonly Dictionary _ballLookup = new(); [NonSerialized] private readonly Dictionary _transforms = new(); @@ -77,6 +78,7 @@ internal void Register(T item) where T : MonoBehaviour case PlungerComponent c: _plungerStates[itemId] = c.CreateState(); break; case SpinnerComponent c: _spinnerStates[itemId] = c.CreateState(); break; case SurfaceComponent c: _surfaceStates[itemId] = c.CreateState(); break; + case TriggerComponent c: _triggerStates[itemId] = c.CreateState(); break; } } @@ -164,13 +166,14 @@ private void Update() PlungerStates = _plungerStates, SpinnerStates = _spinnerStates, SurfaceStates = _surfaceStates, + TriggerStates = _triggerStates, }; var env = _physicsEnv[0]; var state = new PhysicsState(ref env, ref _octree, ref _colliders, ref events, ref _insideOfs, ref _balls, ref _bumperStates, ref _dropTargetStates, ref _flipperStates, ref _gateStates, ref _hitTargetStates, ref _kickerStates, ref _plungerStates, ref _spinnerStates, - ref _surfaceStates); + ref _surfaceStates, ref _triggerStates); // process input while (_inputActions.Count > 0) { @@ -270,6 +273,7 @@ internal struct UpdatePhysicsJob : IJob public NativeParallelHashMap PlungerStates; public NativeParallelHashMap SpinnerStates; public NativeParallelHashMap SurfaceStates; + public NativeParallelHashMap TriggerStates; public void Execute() { @@ -277,7 +281,7 @@ public void Execute() var state = new PhysicsState(ref env, ref Octree, ref Colliders, ref Events, ref InsideOfs, ref Balls, ref BumperStates, ref DropTargetStates, ref FlipperStates, ref GateStates, ref HitTargetStates, ref KickerStates, ref PlungerStates, ref SpinnerStates, - ref SurfaceStates); + ref SurfaceStates, ref TriggerStates); var cycle = new PhysicsCycle(Allocator.Temp); while (env.CurPhysicsFrameTime < InitialTimeUsec) // loop here until current (real) time matches the physics (simulated) time diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index f1d4a8eeb..62002e1a8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -18,6 +18,7 @@ using Unity.Collections; using Unity.Entities; using UnityEngine; +using VisualPinball.Engine.VPT.Surface; using VisualPinball.Unity.Collections; namespace VisualPinball.Unity @@ -39,6 +40,7 @@ internal struct PhysicsState internal NativeParallelHashMap PlungerStates; internal NativeParallelHashMap SpinnerStates; internal NativeParallelHashMap SurfaceStates; + internal NativeParallelHashMap TriggerStates; public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAssetReference colliders, ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeParallelHashMap balls, @@ -46,7 +48,7 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs ref NativeParallelHashMap flipperStates, ref NativeParallelHashMap gateStates, ref NativeParallelHashMap hitTargetStates, ref NativeParallelHashMap kickerStates, ref NativeParallelHashMap plungerStates, ref NativeParallelHashMap spinnerStates, - ref NativeParallelHashMap surfaceStates) + ref NativeParallelHashMap surfaceStates, ref NativeParallelHashMap triggerStates) { Env = env; Octree = octree; @@ -63,6 +65,7 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs PlungerStates = plungerStates; SpinnerStates = spinnerStates; SurfaceStates = surfaceStates; + TriggerStates = triggerStates; } internal Collider GetCollider(int colliderId) => Colliders.Value.Colliders[colliderId].Value; @@ -79,22 +82,64 @@ internal ref PlungerState GetPlungerState(int colliderId) return ref PlungerStates.GetValueByRef(collider.ItemId); } + internal ref SpinnerState GetSpinnerState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return ref SpinnerStates.GetValueByRef(collider.ItemId); + } + + internal ref TriggerState GetTriggerState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return ref TriggerStates.GetValueByRef(collider.ItemId); + } + + internal ref KickerState GetKickerState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return ref KickerStates.GetValueByRef(collider.ItemId); + } + internal bool HasDropTargetState(int colliderId) { var collider = Colliders.Value.Colliders[colliderId].Value; return DropTargetStates.ContainsKey(collider.ItemId); } + internal bool HasHitTargetState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return HitTargetStates.ContainsKey(collider.ItemId); + } + internal ref DropTargetState GetDropTargetState(int colliderId) { var collider = Colliders.Value.Colliders[colliderId].Value; return ref DropTargetStates.GetValueByRef(collider.ItemId); } + internal ref HitTargetState GetHitTargetState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return ref HitTargetStates.GetValueByRef(collider.ItemId); + } + internal ref BumperState GetBumperState(int colliderId) { var collider = Colliders.Value.Colliders[colliderId].Value; return ref BumperStates.GetValueByRef(collider.ItemId); } + + internal ref GateState GetGateState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return ref GateStates.GetValueByRef(collider.ItemId); + } + + internal ref SurfaceState GetSurfaceState(int colliderId) + { + var collider = Colliders.Value.Colliders[colliderId].Value; + return ref SurfaceStates.GetValueByRef(collider.ItemId); + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index c2fb1c88e..9c61be936 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -16,9 +16,9 @@ // ReSharper disable ConvertIfStatementToSwitchStatement -using VisualPinball.Unity; +using VisualPinball.Engine.VPT; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class PhysicsStaticCollision { @@ -38,38 +38,151 @@ internal static void Collide(float hitTime, ref BallData ball, uint timeMs, ref private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState state) { - var collider = state.GetCollider(ball.CollisionEvent.ColliderId); - switch (state.Colliders.GetType(ball.CollisionEvent.ColliderId)) { + var colliderId = ball.CollisionEvent.ColliderId; + var collider = state.GetCollider(colliderId); + if (CollidesWithItem(ref collider, ref ball, ref state)) { + return; + } + + switch (state.Colliders.GetType(colliderId)) { + case ColliderType.Circle: - state.Colliders.GetCircleCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); + state.Colliders.GetCircleCollider(colliderId).Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); break; + case ColliderType.Plane: - state.Colliders.GetPlaneCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); + state.Colliders.GetPlaneCollider(colliderId).Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); break; + case ColliderType.Line: - state.Colliders.GetLineCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + state.Colliders.GetLineCollider(colliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; + case ColliderType.Triangle: - state.Colliders.GetTriangleCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + state.Colliders.GetTriangleCollider(colliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; + case ColliderType.Line3D: - state.Colliders.GetLine3DCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + state.Colliders.GetLine3DCollider(colliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; + case ColliderType.Point: - state.Colliders.GetPointCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + state.Colliders.GetPointCollider(colliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; + case ColliderType.Bumper: - ref var bumperState = ref state.GetBumperState(ball.CollisionEvent.ColliderId); + ref var bumperState = ref state.GetBumperState(colliderId); BumperCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref bumperState.RingAnimation, ref bumperState.SkirtAnimation, in collider, in bumperState.Static, ref state.Env.Random); break; + case ColliderType.Flipper: - ref var flipperState = ref state.GetFlipperState(ball.CollisionEvent.ColliderId); - state.Colliders.GetFlipperCollider(ball.CollisionEvent.ColliderId).Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, + ref var flipperState = ref state.GetFlipperState(colliderId); + state.Colliders.GetFlipperCollider(colliderId).Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, ref state.EventQueue, in ball.Id, in flipperState.Tricks, in flipperState.Static, in flipperState.Velocity, in flipperState.Hit, timeMs); break; + + case ColliderType.Gate: + ref var gateState = ref state.GetGateState(colliderId); + GateCollider.Collide(ref ball, ref ball.CollisionEvent, ref gateState.Movement, ref state.EventQueue, + in collider, in gateState.Static); + break; + + case ColliderType.LineSlingShot: + ref var surfaceState = ref state.GetSurfaceState(colliderId); + state.Colliders.GetLineSlingshotCollider(colliderId).Collide(ref ball, ref state.EventQueue, in surfaceState.Slingshot, + in ball.CollisionEvent, ref state.Env.Random); + break; + + case ColliderType.Plunger: + ref var plungerState = ref state.GetPlungerState(colliderId); + PlungerCollider.Collide(ref ball, ref ball.CollisionEvent, ref plungerState.Movement, in plungerState.Static, ref state.Env.Random); + break; + + case ColliderType.Spinner: + ref var spinnerState = ref state.GetSpinnerState(colliderId); + SpinnerCollider.Collide(in ball, ref ball.CollisionEvent, ref spinnerState.Movement, in spinnerState.Static); + break; + + case ColliderType.TriggerCircle: + case ColliderType.TriggerLine: + ref var triggerState = ref state.GetTriggerState(colliderId); + TriggerCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref state.InsideOfs, ref triggerState.Animation, in collider); + + // if (HasComponent(coll.ItemId)) { + // if (triggerAnimationData.UnHitEvent) { + // var flipperCorrectionData = GetComponent(coll.ItemId); + // ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; + // var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // var flipperTricksData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // FlipperCorrection.OnBallLeaveFlipper( + // ref ballData, ref flipperCorrectionBlob, in flipperMovementData, in flipperTricksData, in flipperStaticData, timeMsec + // ); + // } + // + // } else { + // SetComponent(coll.ItemId, triggerAnimationData); + // } + break; + + case ColliderType.KickerCircle: + ref var kickerState = ref state.GetKickerState(colliderId); + KickerCollider.Collide(ref ball, ref state.EventQueue, ref state.InsideOfs, ref kickerState.Collision, + in kickerState.Static, in kickerState.CollisionMesh, in ball.CollisionEvent, collider.ItemId); + break; + } + } + + private static bool CollidesWithItem(ref Collider collider, ref BallData ball, ref PhysicsState state) + { + // hit target + var colliderId = ball.CollisionEvent.ColliderId; + if (collider.Header.ItemType == ItemType.HitTarget) { + + var normal = collider.Type == ColliderType.Triangle + ? state.Colliders.GetTriangleCollider(colliderId).Normal() + : ball.CollisionEvent.HitNormal; + + if (state.HasDropTargetState(colliderId)) { + ref var dropTargetState = ref state.GetDropTargetState(colliderId); + TargetCollider.DropTargetCollide(ref ball, ref state.EventQueue, ref dropTargetState.Animation, in normal, in ball.CollisionEvent, in collider, ref state.Env.Random); + return true; + } + + if (state.HasHitTargetState(colliderId)) { + ref var hitTargetState = ref state.GetHitTargetState(colliderId); + TargetCollider.HitTargetCollide(ref ball, ref state.EventQueue, ref hitTargetState.Animation, in normal, in ball.CollisionEvent, in collider, ref state.Env.Random); + return true; + } + + // trigger + } else if (collider.Header.ItemType == ItemType.Trigger) { + + ref var triggerState = ref state.GetTriggerState(colliderId); + TriggerCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref state.InsideOfs, ref triggerState.Animation, in collider); + return true; + + // if (HasComponent(collider.ItemId)) { + // if (triggerAnimationData.UnHitEvent) { + // var flipperCorrectionData = GetComponent(collider.ItemId); + // ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; + // var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // var flipperTricksData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // FlipperCorrection.OnBallLeaveFlipper( + // ref ballData, ref flipperCorrectionBlob, in flipperMovementData, in flipperTricksData, in flipperStaticData, timeMsec + // ); + // } + // + // } else { + // SetComponent(collider.ItemId, triggerAnimationData); + // } + } + + return false; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 6175f65b8..4f82c6d45 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -210,7 +210,7 @@ internal static unsafe void Collide(in Collider coll, ref BallData ballData, } } - internal static void FireHitEvent(ref BallData ball, ref NativeQueue.ParallelWriter events, in int ballId, in ColliderHeader collHeader) + internal static void FireHitEvent(ref BallData ball, ref NativeQueue.ParallelWriter events, in ColliderHeader collHeader) { if (collHeader.FireEvents/* && collHeader.IsEnabled*/) { // todo enabled @@ -226,7 +226,7 @@ internal static void FireHitEvent(ref BallData ball, ref NativeQueue. // must be a new place if only by a little if (distLs > normalDist) { - events.Enqueue(new EventData(EventId.HitEventsHit, collHeader.ItemId, ballId, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, collHeader.ItemId, ball.Id, true)); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs index 2ded52709..8846702ae 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs @@ -139,7 +139,7 @@ public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter if (_header.FireEvents && dot >= _header.Threshold && _header.IsPrimitive) { // todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in _header); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index 5a5ad4138..28a484dc7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -236,7 +236,7 @@ public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); if (dot <= -_header.Threshold) { - Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in _header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs index c4678ec4d..dd46f8f97 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs @@ -98,7 +98,7 @@ private static float HitTest(ref CollisionEventData collEvent, ref LineSlingshot #region Collision - public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, in int ballId, in LineSlingshotData slingshotData, in CollisionEventData collEvent, ref Random random) + public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, in LineSlingshotData slingshotData, in CollisionEventData collEvent, ref Random random) { var hitNormal = collEvent.HitNormal; @@ -143,7 +143,7 @@ public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter // !! magic distance, must be a new place if only by a little if (distLs > 0.25f) { - events.Enqueue(new EventData(EventId.SurfaceEventsSlingshot, _header.ItemId, ballId, true)); + events.Enqueue(new EventData(EventId.SurfaceEventsSlingshot, _header.ItemId, ball.Id, true)); // todo slingshot animation // m_slingshotanim.m_TimeReset = g_pplayer->m_time_msec + 100; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs index ce0d9f1ac..48918581c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs @@ -171,7 +171,7 @@ public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); if (dot <= -_header.Threshold) { - Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in _header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs index 094691131..ff36f42e6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs @@ -147,7 +147,7 @@ public void Collide(ref BallData ball, ref NativeQueue.ParallelWrite BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); if (dot <= -_header.Threshold) { - Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in _header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs index c60307a7d..9ba097415 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs @@ -187,7 +187,7 @@ public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter if (_header.FireEvents && dot >= _header.Threshold && _header.IsPrimitive) { // todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in _header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs index 9be357738..88018d4a9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs @@ -132,86 +132,86 @@ protected override void OnUpdate() } case ColliderType.Gate: { - var gateStaticData = GetComponent(coll.ItemId); - var gateMovementData = GetComponent(coll.ItemId); - GateCollider.Collide( - ref ballData, ref collEvent, ref gateMovementData, ref events, - in ballId, in coll, in gateStaticData - ); - SetComponent(coll.ItemId, gateMovementData); + // var gateStaticData = GetComponent(coll.ItemId); + // var gateMovementData = GetComponent(coll.ItemId); + // GateCollider.Collide( + // ref ballData, ref collEvent, ref gateMovementData, ref events, + // in ballId, in coll, in gateStaticData + // ); + // SetComponent(coll.ItemId, gateMovementData); break; } case ColliderType.LineSlingShot: { - var slingshotData = GetComponent(coll.ItemId); - ((LineSlingshotCollider*)collider)->Collide( - ref ballData, ref events, - in ballId, in slingshotData, in collEvent, ref random); + // var slingshotData = GetComponent(coll.ItemId); + // ((LineSlingshotCollider*)collider)->Collide( + // ref ballData, ref events, + // in ballId, in slingshotData, in collEvent, ref random); break; } case ColliderType.Plunger: { - var plungerMovementData = GetComponent(coll.ItemId); - var plungerStaticData = GetComponent(coll.ItemId); - PlungerCollider.Collide( - ref ballData, ref collEvent, ref plungerMovementData, - in plungerStaticData, ref random); - SetComponent(coll.ItemId, plungerMovementData); + // var plungerMovementData = GetComponent(coll.ItemId); + // var plungerStaticData = GetComponent(coll.ItemId); + // PlungerCollider.Collide( + // ref ballData, ref collEvent, ref plungerMovementData, + // in plungerStaticData, ref random); + // SetComponent(coll.ItemId, plungerMovementData); break; } case ColliderType.Spinner: { - var spinnerStaticData = GetComponent(coll.ItemId); - var spinnerMovementData = GetComponent(coll.ItemId); - SpinnerCollider.Collide( - in ballData, ref collEvent, ref spinnerMovementData, - in spinnerStaticData - ); - SetComponent(coll.ItemId, spinnerMovementData); + // var spinnerStaticData = GetComponent(coll.ItemId); + // var spinnerMovementData = GetComponent(coll.ItemId); + // SpinnerCollider.Collide( + // in ballData, ref collEvent, ref spinnerMovementData, + // in spinnerStaticData + // ); + // SetComponent(coll.ItemId, spinnerMovementData); break; } case ColliderType.TriggerCircle: case ColliderType.TriggerLine: { - var triggerAnimationData = HasComponent(coll.ItemId) - ? GetComponent(coll.ItemId) - : new TriggerAnimationData(); + // var triggerAnimationData = HasComponent(coll.ItemId) + // ? GetComponent(coll.ItemId) + // : new TriggerAnimationData(); // TriggerCollider.Collide( // ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, // in ballId, in coll // ); - if (HasComponent(coll.ItemId)) { - if (triggerAnimationData.UnHitEvent) { - var flipperCorrectionData = GetComponent(coll.ItemId); - ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; - var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); - var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); - var flipperTricksData = GetComponent(flipperCorrectionBlob.FlipperEntity); - FlipperCorrection.OnBallLeaveFlipper( - ref ballData, ref flipperCorrectionBlob, in flipperMovementData, in flipperTricksData, in flipperStaticData, timeMsec - ); - } - - } else { - SetComponent(coll.ItemId, triggerAnimationData); - } + // if (HasComponent(coll.ItemId)) { + // if (triggerAnimationData.UnHitEvent) { + // var flipperCorrectionData = GetComponent(coll.ItemId); + // ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; + // var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // var flipperTricksData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // FlipperCorrection.OnBallLeaveFlipper( + // ref ballData, ref flipperCorrectionBlob, in flipperMovementData, in flipperTricksData, in flipperStaticData, timeMsec + // ); + // } + // + // } else { + // SetComponent(coll.ItemId, triggerAnimationData); + // } break; } case ColliderType.KickerCircle: { - var kickerCollisionData = GetComponent(coll.ItemId); - var kickerStaticData = GetComponent(coll.ItemId); - // ReSharper disable once ConditionIsAlwaysTrueOrFalse - var legacyMode = KickerCollider.ForceLegacyMode || kickerStaticData.LegacyMode; - // ReSharper disable once ConditionIsAlwaysTrueOrFalse - var kickerMeshData = !legacyMode ? GetComponent(coll.ItemId) : default; - // KickerCollider.Collide(ref ballData, ref events, ref insideOfs, ref kickerCollisionData, - // in kickerStaticData, in kickerMeshData, in collEvent, coll.ItemId, in ballId - // ); - SetComponent(coll.ItemId, kickerCollisionData); + // var kickerCollisionData = GetComponent(coll.ItemId); + // var kickerStaticData = GetComponent(coll.ItemId); + // // ReSharper disable once ConditionIsAlwaysTrueOrFalse + // var legacyMode = KickerCollider.ForceLegacyMode || kickerStaticData.LegacyMode; + // // ReSharper disable once ConditionIsAlwaysTrueOrFalse + // var kickerMeshData = !legacyMode ? GetComponent(coll.ItemId) : default; + // // KickerCollider.Collide(ref ballData, ref events, ref insideOfs, ref kickerCollisionData, + // // in kickerStaticData, in kickerMeshData, in collEvent, coll.ItemId, in ballId + // // ); + // SetComponent(coll.ItemId, kickerCollisionData); break; } @@ -223,58 +223,58 @@ in spinnerStaticData case ColliderType.Point: case ColliderType.Triangle: - // hit target - if (coll.Header.ItemType == ItemType.HitTarget) { - - var normal = coll.Type == ColliderType.Triangle - ? ((TriangleCollider*) collider)->Normal() - : collEvent.HitNormal; - - if (HasComponent(coll.ItemId)) { - var dropTargetAnimationData = GetComponent(coll.ItemId); - TargetCollider.DropTargetCollide(ref ballData, ref events, ref dropTargetAnimationData, - in normal, in ballId, in collEvent, in coll, ref random); - SetComponent(coll.ItemId, dropTargetAnimationData); - } - - if (HasComponent(coll.ItemId)) { - var hitTargetAnimationData = GetComponent(coll.ItemId); - TargetCollider.HitTargetCollide(ref ballData, ref events, ref hitTargetAnimationData, - in normal, in ballId, in collEvent, in coll, ref random); - SetComponent(coll.ItemId, hitTargetAnimationData); - } - - // trigger - } else if (coll.Header.ItemType == ItemType.Trigger) { - - var triggerAnimationData = HasComponent(coll.ItemId) - ? GetComponent(coll.ItemId) - : new TriggerAnimationData(); - - // TriggerCollider.Collide( - // ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, - // in ballId, in coll - // ); - - if (HasComponent(coll.ItemId)) { - if (triggerAnimationData.UnHitEvent) { - var flipperCorrectionData = GetComponent(coll.ItemId); - ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; - var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); - var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); - var flipperTricksData = GetComponent(flipperCorrectionBlob.FlipperEntity); - FlipperCorrection.OnBallLeaveFlipper( - ref ballData, ref flipperCorrectionBlob, in flipperMovementData, in flipperTricksData, in flipperStaticData, timeMsec - ); - } - - } else { - SetComponent(coll.ItemId, triggerAnimationData); - } - - } else { - Collider.Collide(in coll, ref ballData, ref events, in ballId, in collEvent, ref random); - } + // // hit target + // if (coll.Header.ItemType == ItemType.HitTarget) { + // + // var normal = coll.Type == ColliderType.Triangle + // ? ((TriangleCollider*) collider)->Normal() + // : collEvent.HitNormal; + // + // if (HasComponent(coll.ItemId)) { + // var dropTargetAnimationData = GetComponent(coll.ItemId); + // TargetCollider.DropTargetCollide(ref ballData, ref events, ref dropTargetAnimationData, + // in normal, in ballId, in collEvent, in coll, ref random); + // SetComponent(coll.ItemId, dropTargetAnimationData); + // } + // + // if (HasComponent(coll.ItemId)) { + // var hitTargetAnimationData = GetComponent(coll.ItemId); + // TargetCollider.HitTargetCollide(ref ballData, ref events, ref hitTargetAnimationData, + // in normal, in ballId, in collEvent, in coll, ref random); + // SetComponent(coll.ItemId, hitTargetAnimationData); + // } + // + // // trigger + // } else if (coll.Header.ItemType == ItemType.Trigger) { + // + // var triggerAnimationData = HasComponent(coll.ItemId) + // ? GetComponent(coll.ItemId) + // : new TriggerAnimationData(); + // + // // TriggerCollider.Collide( + // // ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, + // // in ballId, in coll + // // ); + // + // if (HasComponent(coll.ItemId)) { + // if (triggerAnimationData.UnHitEvent) { + // var flipperCorrectionData = GetComponent(coll.ItemId); + // ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; + // var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // var flipperTricksData = GetComponent(flipperCorrectionBlob.FlipperEntity); + // FlipperCorrection.OnBallLeaveFlipper( + // ref ballData, ref flipperCorrectionBlob, in flipperMovementData, in flipperTricksData, in flipperStaticData, timeMsec + // ); + // } + // + // } else { + // SetComponent(coll.ItemId, triggerAnimationData); + // } + // + // } else { + // Collider.Collide(in coll, ref ballData, ref events, in ballId, in collEvent, ref random); + // } break; case ColliderType.None: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs index f621de0bf..8a0dd3542 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs @@ -86,7 +86,7 @@ public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, #region Collision public static void Collide(ref BallData ball, ref CollisionEventData collEvent, ref GateMovementData movementData, - ref NativeQueue.ParallelWriter events, in int ballId, in Collider coll, in GateStaticData data) + ref NativeQueue.ParallelWriter events, in Collider coll, in GateStaticData data) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); var h = data.Height * 0.5f; @@ -114,7 +114,7 @@ public static void Collide(ref BallData ball, ref CollisionEventData collEvent, movementData.AngleSpeed = -movementData.AngleSpeed; } - Collider.FireHitEvent(ref ball, ref events, in ballId, in coll.Header); + Collider.FireHitEvent(ref ball, ref events, in coll.Header); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs index 6176fa7f6..58ab0b8f7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Entities; using Unity.Mathematics; namespace VisualPinball.Unity @@ -23,7 +22,7 @@ namespace VisualPinball.Unity internal static class TargetCollider { public static void DropTargetCollide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, - ref DropTargetAnimationData animationData, in float3 normal, in int ballId, in CollisionEventData collEvent, + ref DropTargetAnimationData animationData, in float3 normal, in CollisionEventData collEvent, in Collider coll, ref Random random) { if (animationData.IsDropped) { @@ -36,12 +35,12 @@ public static void DropTargetCollide(ref BallData ball, ref NativeQueue= coll.Threshold && !animationData.IsDropped) { animationData.HitEvent = true; //todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in coll.Header); + Collider.FireHitEvent(ref ball, ref hitEvents, in coll.Header); } } public static void HitTargetCollide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, - ref HitTargetAnimationData animationData, in float3 normal, in int ballId, in CollisionEventData collEvent, + ref HitTargetAnimationData animationData, in float3 normal, in CollisionEventData collEvent, in Collider coll, ref Random random) { var dot = -math.dot(collEvent.HitNormal, ball.Velocity); @@ -50,7 +49,7 @@ public static void HitTargetCollide(ref BallData ball, ref NativeQueue= coll.Threshold) { animationData.HitEvent = true; //todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in ballId, in coll.Header); + Collider.FireHitEvent(ref ball, ref hitEvents, in coll.Header); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs index b1655003d..24e13ea28 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs @@ -19,6 +19,7 @@ using Unity.Mathematics; using VisualPinball.Engine.Common; using VisualPinball.Engine.Game; +using VisualPinball.Unity.Collections; namespace VisualPinball.Unity { @@ -29,12 +30,11 @@ internal static class KickerCollider /// resulting in stutter. Disabling this until we find another /// solution. /// - public const bool ForceLegacyMode = true; + public const bool ForceLegacyMode = false; public static void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, - ref InsideOfs insideOfs, ref KickerCollisionData collData, - in KickerStaticData staticData, in ColliderMeshData meshData, in CollisionEventData collEvent, - in int itemId, in int ballId) + ref InsideOfs insideOfs, ref KickerCollisionData collData, in KickerStaticData staticData, + in ColliderMeshData meshData, in CollisionEventData collEvent, in int itemId) { // a previous ball already in kicker? if (collData.HasBall) { @@ -47,7 +47,7 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle var hitBit = collEvent.HitFlag; // check if kicker in ball's volume set - var isBallInside = insideOfs.IsInsideOf(itemId, ballId); + var isBallInside = insideOfs.IsInsideOf(itemId, ball.Id); // New or (Hit && !Vol || UnHit && Vol) if (hitBit == isBallInside) { @@ -84,12 +84,12 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle ball.IsFrozen = !staticData.FallThrough; if (ball.IsFrozen) { insideOfs.SetInsideOf(itemId, ball.Id); // add kicker to ball's volume set - collData.BallId = ballId; - collData.LastCapturedBallId = ballId; + collData.BallId = ball.Id; + collData.LastCapturedBallId = ball.Id; } // Fire the event before changing ball attributes, so scripters can get a useful ball state - events.Enqueue(new EventData(EventId.HitEventsHit, itemId, ballId, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, itemId, ball.Id, true)); if (ball.IsFrozen || staticData.FallThrough) { // script may have unfrozen the ball @@ -116,7 +116,7 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle } else { // exiting kickers volume // remove kicker to ball's volume set insideOfs.SetOutsideOf(itemId, ball.Id); - events.Enqueue(new EventData(EventId.HitEventsUnhit, itemId, ballId, true)); + events.Enqueue(new EventData(EventId.HitEventsUnhit, itemId, ball.Id, true)); } } } @@ -129,7 +129,7 @@ private static void DoChangeBallVelocity(ref BallData ball, in float3 hitNormal, ref var hitMeshNormals = ref meshData.Value.Value.Normals; for (var t = 0; t < hitMesh.Length; t++) { // find the right normal by calculating the distance from current ball position to vertex of the kicker mesh - ref var vertex = ref hitMesh[t].Vertex; + ref var vertex = ref hitMesh[t]; var lengthSqr = math.lengthsq(ball.Position - vertex); if (lengthSqr < minDistSqr) { minDistSqr = lengthSqr; @@ -140,7 +140,7 @@ private static void DoChangeBallVelocity(ref BallData ball, in float3 hitNormal, if (idx != ~0u) { // we have the nearest vertex now use the normal and damp it so it doesn't speed up the ball velocity too much - ref var hitNorm = ref hitMeshNormals[(int)idx].Vertex; + ref var hitNorm = ref hitMeshNormals[(int)idx]; var dot = -math.dot(ball.Velocity, hitNorm); var reactionImpulse = ball.Mass * math.abs(dot); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderMeshData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderMeshData.cs index 144673475..6c7807049 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderMeshData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderMeshData.cs @@ -14,24 +14,40 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System.Collections.Generic; +using Unity.Collections; using Unity.Entities; using Unity.Mathematics; +using VisualPinball.Engine.Math; namespace VisualPinball.Unity { - internal struct ColliderMeshData : IComponentData - { - public BlobAssetReference Value; - } - public struct KickerMeshVertexBlobAsset { - public BlobArray Vertices; - public BlobArray Normals; + public BlobArray Vertices; + public BlobArray Normals; } - public struct KickerMeshVertex + internal struct ColliderMeshData { - public float3 Vertex; + public BlobAssetReference Value; + + public ColliderMeshData(IList vertices, float radius, float3 position) + { + var rad = radius * 0.8f; + using var blobBuilder = new BlobBuilder(Allocator.Temp); + ref var blobAsset = ref blobBuilder.ConstructRoot(); + var blobVertices = blobBuilder.Allocate(ref blobAsset.Vertices, vertices.Count); + var blobNormals = blobBuilder.Allocate(ref blobAsset.Normals, vertices.Count); + for (var i = 0; i < vertices.Count; i++) { + blobVertices[i] = new float3( + vertices[i].X * rad + position.x, + vertices[i].Y * rad + position.y, + vertices[i].Z * rad + position.z + ); + blobNormals[i] = new float3(vertices[i].Nx, vertices[i].Ny, vertices[i].Nz); + } + Value = blobBuilder.CreateBlobAssetReference(Allocator.Persistent); + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs index ab9d8ce75..ac7d76b20 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs @@ -25,6 +25,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using Unity.Collections; +using Unity.Entities; using Unity.Mathematics; using UnityEditor; using UnityEngine; @@ -272,31 +274,20 @@ internal KickerState CreateState() FallThrough = colliderComponent.FallThrough, HitAccuracy = colliderComponent.HitAccuracy, Scatter = colliderComponent.Scatter, - LegacyMode = true, // todo colliderComponent.LegacyMode, + LegacyMode = colliderComponent.LegacyMode, ZLow = Surface?.Height(Position) ?? PlayfieldHeight } : default; - // if (!Data.LegacyMode) { - // // todo currently we don't allow non-legacy mode - // using (var blobBuilder = new BlobBuilder(Allocator.Temp)) { - // ref var blobAsset = ref blobBuilder.ConstructRoot(); - // var vertices = blobBuilder.Allocate(ref blobAsset.Vertices, Item.KickerHit.HitMesh.Length); - // var normals = blobBuilder.Allocate(ref blobAsset.Normals, Item.KickerHit.HitMesh.Length); - // for (var i = 0; i < Item.KickerHit.HitMesh.Length; i++) { - // var v = Item.KickerHit.HitMesh[i]; - // vertices[i] = new KickerMeshVertex { Vertex = v.ToUnityFloat3() }; - // normals[i] = new KickerMeshVertex { Vertex = new float3(KickerHitMesh.Vertices[i].Nx, KickerHitMesh.Vertices[i].Ny, KickerHitMesh.Vertices[i].Nz) }; - // } - // - // var blobAssetReference = blobBuilder.CreateBlobAssetReference(Allocator.Persistent); - // dstManager.AddComponentData(entity, new ColliderMeshData { Value = blobAssetReference }); - // } - // } + var height = SurfaceHeight(Surface, Position); + var meshData = colliderComponent.LegacyMode + ? new ColliderMeshData(Array.Empty(), 0, float3.zero) + : new ColliderMeshData(KickerHitMesh.Vertices, Radius, new float3(Center.x, Center.y, height)); return new KickerState( colliderComponent ? colliderComponent.gameObject.GetInstanceID() : 0, staticData, - new KickerCollisionData() + new KickerCollisionData(), + meshData ); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs index e9fcb4654..9e495eba4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs @@ -21,12 +21,14 @@ internal struct KickerState internal readonly int ItemId; internal KickerStaticData Static; internal KickerCollisionData Collision; + internal ColliderMeshData CollisionMesh; - public KickerState(int itemId, KickerStaticData @static, KickerCollisionData collision) + public KickerState(int itemId, KickerStaticData @static, KickerCollisionData collision, ColliderMeshData collisionMesh) { ItemId = itemId; Static = @static; Collision = collision; + CollisionMesh = collisionMesh; } } } From 241498b2a7a3dc17be75ba9471b6ecf6c1c7b9f8 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 5 Oct 2023 23:38:17 +0200 Subject: [PATCH 064/159] jobs: Enable colliders for all items. --- .../VisualPinball.Unity/Game/InsideOfs.cs | 4 ++-- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 6 +----- .../VPT/Bumper/BumperColliderComponent.cs | 9 +-------- .../VisualPinball.Unity/VPT/ColliderComponent.cs | 6 +++++- .../VPT/Flipper/FlipperColliderComponent.cs | 7 +------ .../VPT/HitTarget/DropTargetColliderComponent.cs | 2 -- .../VPT/Playfield/PlayfieldColliderComponent.cs | 7 +------ .../VPT/Primitive/PrimitiveColliderComponent.cs | 7 +------ .../VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs | 2 +- 9 files changed, 13 insertions(+), 37 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs index 550967605..e9a769968 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs @@ -50,7 +50,7 @@ private void ClearItems(int itemId) private void ClearBitIndex(int ballId) { - var maps = _insideOfs.GetValueArray(Allocator.TempJob); + var maps = _insideOfs.GetValueArray(Allocator.Temp); var index = GetBitIndex(ballId); foreach (var ballIndices in maps) { if (!ballIndices.IsSet(index)) { @@ -68,7 +68,7 @@ private int GetBitIndex(int ballId) return _bitLookup[ballId]; } - var indices = _bitLookup.GetValueArray(Allocator.TempJob); + var indices = _bitLookup.GetValueArray(Allocator.Temp); for (var i = 0; i < 64; i++) { if (indices.Contains(i)) { continue; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index a70923cef..6cdbda07d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -62,11 +62,7 @@ internal void Register(T item) where T : MonoBehaviour { var go = item.gameObject; var itemId = go.GetInstanceID(); - if (_transforms.ContainsKey(itemId)) { - // animation components are always added, sometimes they overlap with the main component (i.e. triggers) - return; - } - _transforms.Add(itemId, go.transform); + _transforms.TryAdd(itemId, go.transform); switch (item) { case BumperComponent c: _bumperStates[itemId] = c.CreateState(); break; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs index 7372013a6..1cf66593d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs @@ -16,14 +16,13 @@ // ReSharper disable InconsistentNaming -using System.Collections.Generic; using UnityEngine; using VisualPinball.Engine.VPT.Bumper; namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Collision/Bumper Collider")] - public class BumperColliderComponent : ColliderComponent, ICollidableComponent + public class BumperColliderComponent : ColliderComponent { #region Data @@ -47,12 +46,6 @@ public class BumperColliderComponent : ColliderComponent new BumperApi(gameObject, player); - - void ICollidableComponent.GetColliders(Player player, List colliders, float margin) - { - InstantiateColliderApi(player).CreateColliders(colliders, margin); - } - public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(scatterAngleDeg: Scatter); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index 498ba3b1f..417d9eabf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -34,7 +34,7 @@ namespace VisualPinball.Unity { [DisallowMultipleComponent] public abstract class ColliderComponent : SubComponent, - IColliderComponent + IColliderComponent, ICollidableComponent where TData : ItemData where TMainComponent : MainComponent { @@ -457,6 +457,10 @@ private static void DrawAabb(Aabb aabb, bool isSelected) #endregion + void ICollidableComponent.GetColliders(Player player, List colliders, float margin) + { + InstantiateColliderApi(player).CreateColliders(colliders, margin); + } #endif } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs index 91d7190fa..b179b75b7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs @@ -25,7 +25,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Collision/Flipper Collider")] [HelpURL("https://docs.visualpinball.org/creators-guide/manual/mechanisms/flippers.html")] - public class FlipperColliderComponent : ColliderComponent, ICollidableComponent + public class FlipperColliderComponent : ColliderComponent { #region Data @@ -162,10 +162,5 @@ public class FlipperColliderComponent : ColliderComponent new FlipperApi(gameObject, player); - - void ICollidableComponent.GetColliders(Player player, List colliders, float margin) - { - InstantiateColliderApi(player).CreateColliders(colliders, margin); - } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs index e111a8d36..54d155efb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs @@ -16,8 +16,6 @@ // ReSharper disable InconsistentNaming -using System; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.HitTarget; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs index 45c333f1e..e5d04059e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs @@ -24,7 +24,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Collision/Playfield Collider")] - public class PlayfieldColliderComponent : ColliderComponent, ICollidableComponent + public class PlayfieldColliderComponent : ColliderComponent { #region Data @@ -56,10 +56,5 @@ public class PlayfieldColliderComponent : ColliderComponent GetPhysicsMaterialData(0, 0); protected override IApiColliderGenerator InstantiateColliderApi(Player player) => new PlayfieldApi(gameObject, player); - - void ICollidableComponent.GetColliders(Player player, List colliders, float margin) - { - InstantiateColliderApi(player).CreateColliders(colliders, margin); - } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs index cd0733444..f3b6157ab 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity { [AddComponentMenu("Visual Pinball/Collision/Primitive Collider")] - public class PrimitiveColliderComponent : ColliderComponent, ICollidableComponent + public class PrimitiveColliderComponent : ColliderComponent { #region Data @@ -62,10 +62,5 @@ public class PrimitiveColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); protected override IApiColliderGenerator InstantiateColliderApi(Player player) => new PrimitiveApi(gameObject, player); - - void ICollidableComponent.GetColliders(Player player, List colliders, float margin) - { - InstantiateColliderApi(player).CreateColliders(colliders, margin); - } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs index 896b4702d..6e396e133 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs @@ -86,7 +86,7 @@ private void Awake() // register at player GetComponentInParent().RegisterTrigger(this); - if (GetComponentInChildren() && GetComponentInChildren() && GetComponentInChildren()) { + if (GetComponentInChildren()) { GetComponentInParent().Register(this); } } From 04c08478495fdb441d02a84196036c5c4bb12962 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 6 Oct 2023 23:22:48 +0200 Subject: [PATCH 065/159] jobs: Fix size of octree. --- VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 6cdbda07d..92f46bf0a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -107,7 +107,7 @@ private void Start() // create octree var elapsedMs = sw.Elapsed.TotalMilliseconds; var playfieldBounds = GetComponentInChildren().Bounds; - _octree = new NativeOctree(playfieldBounds, 32, 10, Allocator.Persistent); + _octree = new NativeOctree(playfieldBounds, 1024, 10, Allocator.Persistent); sw.Restart(); var populateJob = new PopulatePhysicsJob { From e86fcc8f4c68b0141301d69b69bb1167b2a478d7 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 7 Oct 2023 23:26:38 +0200 Subject: [PATCH 066/159] jobs: Accelerate primitive collider generation 8x by using AcquireReadOnlyMeshData() instead of .vertices. --- .../Extensions/MeshExtensions.cs | 27 ++++--- .../Physics/Collider/ColliderUtils.cs | 50 ++++++++++++- .../Collision/StaticNarrowPhaseSystem.cs | 6 +- .../VPT/MainRenderableComponent.cs | 9 +++ .../VPT/Primitive/PrimitiveApi.cs | 2 +- .../Primitive/PrimitiveColliderGenerator.cs | 74 ++++++++++++++----- 6 files changed, 132 insertions(+), 36 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Extensions/MeshExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Extensions/MeshExtensions.cs index 458063a31..4b2881552 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Extensions/MeshExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Extensions/MeshExtensions.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System; +using Unity.Collections; using UnityEngine; using UnityEngine.Rendering; using VisualPinball.Engine.Math; @@ -28,19 +29,21 @@ public static class MeshExtensions public static Mesh ToVpMesh(this UnityEngine.Mesh unityMesh) { + using var meshDataArray = UnityEngine.Mesh.AcquireReadOnlyMeshData(unityMesh); + var meshData = meshDataArray[0]; var vpMesh = new Mesh(unityMesh.name) { - Vertices = new Vertex3DNoTex2[unityMesh.vertexCount] + Vertices = new Vertex3DNoTex2[meshData.vertexCount] }; - var unityVertices = unityMesh.vertices; - var unityNormals = unityMesh.normals; + var unityVertices = new NativeArray(meshData.vertexCount, Allocator.TempJob); + var unityNormals = new NativeArray(meshData.vertexCount, Allocator.TempJob); + meshData.GetVertices(unityVertices); + meshData.GetNormals(unityNormals); for (var i = 0; i < vpMesh.Vertices.Length; i++) { - var unityVertex = unityVertices[i]; - var unityNormal = unityNormals[i]; var unityUv = unityMesh.uv[i]; vpMesh.Vertices[i] = new Vertex3DNoTex2( - unityVertex.x, unityVertex.y, unityVertex.z, - unityNormal.x, unityNormal.y, unityNormal.z, + unityVertices[i].x, unityVertices[i].y, unityVertices[i].z, + unityNormals[i].x, unityNormals[i].y, unityNormals[i].z, unityUv.x, -unityUv.y ); } vpMesh.Indices = unityMesh.triangles; @@ -62,17 +65,18 @@ public static Mesh ToVpMesh(this UnityEngine.Mesh unityMesh) var frameData = new Mesh.VertData[unityMesh.vertexCount]; for (var j = 0; j < unityMesh.vertexCount; j++) { - var vertex = deltaVertices[j] + unityVertices[j]; - var normal = deltaNormals[j] + unityNormals[j]; frameData[j] = new Mesh.VertData( - vertex.x, vertex.y, vertex.z, - normal.x, normal.y, normal.z); + deltaVertices[j].x + unityVertices[j].x, deltaVertices[j].y + unityVertices[j].y, deltaVertices[j].z + unityVertices[j].z, + deltaNormals[j].x + unityNormals[j].x, deltaNormals[j].y + unityNormals[j].y, deltaNormals[j].z + unityNormals[j].z); } vpMesh.AnimationFrames.Add(frameData); } } + unityVertices.Dispose(); + unityNormals.Dispose(); + return vpMesh; } @@ -152,4 +156,3 @@ public static Vector3 ToUnityNormalVector3(this Mesh.VertData vpVert) } } } - diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs index 1d39d9842..852cd2775 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs @@ -15,14 +15,19 @@ // along with this program. If not, see . using System.Collections.Generic; +using Unity.Collections; using Unity.Mathematics; +using Unity.Profiling; +using UnityEngine; using VisualPinball.Engine.Math; -using VisualPinball.Engine.VPT; +using Mesh = VisualPinball.Engine.VPT.Mesh; namespace VisualPinball.Unity { public static class ColliderUtils { + private static readonly ProfilerMarker PerfMarker1 = new("ColliderUtils.GenerateCollidersFromMesh"); + public static void Generate3DPolyColliders(in float3[] rgv, ColliderInfo info, ICollection colliders) { var inputVerts = new float2[rgv.Length]; @@ -46,6 +51,7 @@ public static void Generate3DPolyColliders(in float3[] rgv, ColliderInfo info, I public static void GenerateCollidersFromMesh(Mesh mesh, ColliderInfo info, ICollection colliders, bool onlyTriangles = false) { + PerfMarker1.Begin(); var addedEdges = EdgeSet.Get(); // add collision triangles and edges @@ -82,6 +88,48 @@ public static void GenerateCollidersFromMesh(Mesh mesh, ColliderInfo info, IColl colliders.Add(new PointCollider(vertex.ToUnityFloat3(), info)); } } + PerfMarker1.End(); + } + + public static void GenerateCollidersFromMesh(in NativeArray vertices, in NativeArray indices, ref Matrix4x4 matrix, ColliderInfo info, ICollection colliders, bool onlyTriangles = false) + { + PerfMarker1.Begin(); + var addedEdges = EdgeSet.Get(); + + // add collision triangles and edges + for (var i = 0; i < indices.Length; i += 3) { + var i0 = indices[i]; + var i1 = indices[i + 1]; + var i2 = indices[i + 2]; + + // NB: HitTriangle wants CCW vertices, but for rendering we have them in CW order + var rgv0 = matrix.MultiplyPoint(vertices[i0]); + var rgv1 = matrix.MultiplyPoint(vertices[i1]); + var rgv2 = matrix.MultiplyPoint(vertices[i2]); + + colliders.Add(new TriangleCollider(rgv0, rgv2, rgv1, info)); + + if (!onlyTriangles) { + + if (addedEdges.ShouldAddHitEdge(i0, i1)) { + colliders.Add(new Line3DCollider(rgv0, rgv2, info)); + } + if (addedEdges.ShouldAddHitEdge(i1, i2)) { + colliders.Add(new Line3DCollider(rgv2, rgv1, info)); + } + if (addedEdges.ShouldAddHitEdge(i2, i0)) { + colliders.Add(new Line3DCollider(rgv1, rgv0, info)); + } + } + } + + // add collision vertices + if (!onlyTriangles) { + foreach (var vertex in vertices) { + colliders.Add(new PointCollider(matrix.MultiplyPoint(vertex), info)); + } + } + PerfMarker1.End(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs index 798cb9718..f0ef22dc1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs @@ -16,11 +16,11 @@ using Unity.Collections; using Unity.Entities; -using Unity.Mathematics; using Unity.Profiling; -using VisualPinball.Engine.VPT; +using UnityEngine; using VisualPinball.Unity; using VisualPinball.Unity.VisualPinball.Unity.Game; +using Collider = VisualPinball.Unity.Collider; namespace VisualPinballUnity { @@ -46,7 +46,7 @@ protected override void OnUpdate() var collData = EntityManager.GetComponentData(collEntity); var contacts = _simulateCycleSystemGroup.Contacts; var hitTime = _simulateCycleSystemGroup.HitTime; - var random = new Random((uint)UnityEngine.Random.Range(1, 100000)); + var random = new Unity.Mathematics.Random((uint)Random.Range(1, 100000)); var marker = PerfMarker; Entities diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs index a36427edf..1fe501f77 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs @@ -80,6 +80,15 @@ protected Mesh GetDefaultMesh() return null; } + public UnityEngine.Mesh GetUnityMesh() + { + var mf = GetComponent(); + if (mf && mf.sharedMesh) { + return mf.sharedMesh; + } + return null; + } + public virtual void OnPlayfieldHeightUpdated() => UpdateTransforms(); public virtual void UpdateTransforms() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs index 75847cd7c..dff33ec5b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs @@ -45,7 +45,7 @@ internal PrimitiveApi(GameObject go, Player player) : base(go, player) protected override void CreateColliders(List colliders, float margin) { - var colliderGenerator = new PrimitiveColliderGenerator(this, MainComponent); + var colliderGenerator = new PrimitiveColliderGenerator(this, MainComponent, MainComponent); colliderGenerator.GenerateColliders(ColliderComponent.CollisionReductionFactor, colliders); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderGenerator.cs index b91b0c8e0..ac637f12c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderGenerator.cs @@ -18,14 +18,18 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using NLog; +using Unity.Collections; using Unity.Mathematics; +using Unity.Profiling; +using UnityEngine; using VisualPinball.Engine.Math; using VisualPinball.Engine.Math.Mesh; using VisualPinball.Engine.VPT; -using MathF = VisualPinball.Engine.Math.MathF; +using Debug = System.Diagnostics.Debug; +using Logger = NLog.Logger; +using Mesh = VisualPinball.Engine.VPT.Mesh; namespace VisualPinball.Unity { @@ -33,50 +37,82 @@ public class PrimitiveColliderGenerator { private readonly IApiColliderGenerator _api; private readonly IMeshGenerator _meshGenerator; + private readonly PrimitiveComponent _primitiveComponent; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + private static readonly ProfilerMarker PerfMarker1 = new("PrimitiveColliderGenerator"); + private static readonly ProfilerMarker PerfMarker2 = new("PrimitiveColliderGenerator.reduce"); + private static readonly ProfilerMarker PerfMarker3 = new("PrimitiveColliderGenerator.generate"); - public PrimitiveColliderGenerator(IApiColliderGenerator primitiveApi, IMeshGenerator meshGenerator) + public PrimitiveColliderGenerator(IApiColliderGenerator primitiveApi, IMeshGenerator meshGenerator, PrimitiveComponent primitiveComponent) { _api = primitiveApi; _meshGenerator = meshGenerator; + _primitiveComponent = primitiveComponent; } internal void GenerateColliders(float collisionReductionFactor, List colliders) { - var mesh = _meshGenerator.GetMesh(); - if (mesh == null) { + PerfMarker1.Begin(); + //var mesh = _meshGenerator.GetMesh(); + var unityMesh = _primitiveComponent.GetUnityMesh(); + if (unityMesh == null) { Logger.Warn($"Primitive {_meshGenerator.name} did not return a mesh for collider generation."); return; } - mesh = mesh.Transform(_meshGenerator.GetTransformationMatrix().TransformToVpx()); + + using var meshDataArray = UnityEngine.Mesh.AcquireReadOnlyMeshData(unityMesh); + var meshData = meshDataArray[0]; + var subMesh = meshData.GetSubMesh(0); // todo loop through all sub meshes? + // var vpMesh = new Mesh(unityMesh.name) { + // Vertices = new Vertex3DNoTex2[meshData.vertexCount] + // }; + var unityVertices = new NativeArray(meshData.vertexCount, Allocator.TempJob); + var unityIndices = new NativeArray(subMesh.indexCount, Allocator.TempJob); + meshData.GetVertices(unityVertices); + meshData.GetIndices(unityIndices, 0); var reducedVertices = math.max( - (uint) MathF.Pow(mesh.Vertices.Length, - MathF.Clamp(1f - collisionReductionFactor, 0f, 1f) * 0.25f + 0.75f), + (uint) math.pow(meshData.vertexCount, + math.clamp(1f - collisionReductionFactor, 0f, 1f) * 0.25f + 0.75f), 420u //!! 420 = magic ); - if (reducedVertices < mesh.Vertices.Length) { - mesh = ComputeReducedMesh(mesh, reducedVertices); + PerfMarker2.Begin(); + if (reducedVertices < meshData.vertexCount) { + var mesh = ComputeReducedMesh(in unityVertices, in unityIndices, reducedVertices); + unityIndices.Dispose(); + unityVertices.Dispose(); + + var meshVertices = mesh.Vertices.Select(v => v.ToUnityVector3()).ToArray(); + unityVertices = new NativeArray(meshVertices, Allocator.TempJob); + unityIndices = new NativeArray(mesh.Indices, Allocator.TempJob); } + PerfMarker2.End(); + + PerfMarker3.Begin(); + var worldToVpx = _meshGenerator.GetTransformationMatrix().TransformToVpx().ToUnityMatrix(); + ColliderUtils.GenerateCollidersFromMesh(in unityVertices, in unityIndices, ref worldToVpx, _api.GetColliderInfo(), colliders); + PerfMarker3.End(); + PerfMarker1.End(); - ColliderUtils.GenerateCollidersFromMesh(mesh, _api.GetColliderInfo(), colliders); + unityVertices.Dispose(); + unityIndices.Dispose(); } - private static Mesh ComputeReducedMesh(Mesh mesh, uint reducedVertices) + private static Mesh ComputeReducedMesh(in NativeArray vertices, in NativeArray indices, uint reducedVertices) { - var progVertices = mesh.Vertices - .Select(v =>new ProgMeshFloat3(v.X, v.Y, v.Z)) + var progVertices = vertices + .Select(v => new ProgMeshFloat3(v.x, v.y, v.z)) .ToArray(); - var progIndices = new ProgMeshTriData[mesh.Indices.Length / 3]; + var progIndices = new ProgMeshTriData[indices.Length / 3]; var i2 = 0; - for (var i = 0; i < mesh.Indices.Length; i += 3) { + for (var i = 0; i < indices.Length; i += 3) { var t = new ProgMeshTriData( - mesh.Indices[i], - mesh.Indices[i + 1], - mesh.Indices[i + 2] + indices[i], + indices[i + 1], + indices[i + 2] ); if (t.V[0] != t.V[1] && t.V[1] != t.V[2] && t.V[2] != t.V[0]) { progIndices[i2++] = t; From d66dc7276efeddc2f3f398384836d30cd1fb18a0 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 8 Oct 2023 00:31:47 +0200 Subject: [PATCH 067/159] jobs: Move ColliderRef code into state. --- .../VisualPinball.Unity/Game/PhysicsState.cs | 87 +++++++++++++- .../Game/PhysicsStaticNarrowPhase.cs | 7 +- .../Physics/Collider/ColliderRef.cs | 110 ------------------ .../Physics/Collider/ColliderRef.cs.meta | 3 - 4 files changed, 88 insertions(+), 119 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 62002e1a8..6623f2932 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -17,8 +17,7 @@ using NativeTrees; using Unity.Collections; using Unity.Entities; -using UnityEngine; -using VisualPinball.Engine.VPT.Surface; +using VisualPinball.Engine.VPT; using VisualPinball.Unity.Collections; namespace VisualPinball.Unity @@ -70,6 +69,8 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs internal Collider GetCollider(int colliderId) => Colliders.Value.Colliders[colliderId].Value; + #region States + internal ref FlipperState GetFlipperState(int colliderId) { var collider = Colliders.Value.Colliders[colliderId].Value; @@ -141,5 +142,87 @@ internal ref SurfaceState GetSurfaceState(int colliderId) var collider = Colliders.Value.Colliders[colliderId].Value; return ref SurfaceStates.GetValueByRef(collider.ItemId); } + + #endregion + + #region Hit Test + + internal float HitTest(int colliderId, ref BallData ball, ref CollisionEventData collEvent, ref NativeList contacts, ref PhysicsState state) + { + if (IsInactiveDropTarget(colliderId)) { + return -1f; + } + switch (Colliders.GetType(colliderId)) { + case ColliderType.Bumper: + case ColliderType.Circle: + return Colliders.GetCircleCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime); + + case ColliderType.Gate: + return Colliders.GetGateCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime); + + case ColliderType.Line: + return Colliders.GetLineCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime); + + case ColliderType.LineZ: + return Colliders.GetLineZCollider(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + + case ColliderType.Line3D: + return Colliders.GetLine3DCollider(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + + case ColliderType.LineSlingShot: + return Colliders.GetLineSlingshotCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); + + case ColliderType.Point: + return Colliders.GetPointCollider(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + + case ColliderType.Plane: + return Colliders.GetPlaneCollider(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + + case ColliderType.Spinner: + return Colliders.GetSpinnerCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime); + + case ColliderType.Triangle: + return Colliders.GetTriangleCollider(colliderId).HitTest(ref collEvent, in state.InsideOfs, in ball, + ball.CollisionEvent.HitTime); + + case ColliderType.KickerCircle: + case ColliderType.TriggerCircle: + return Colliders.GetCircleCollider(colliderId).HitTestBasicRadius(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime, false, false, false); + + case ColliderType.TriggerLine: + return Colliders.GetLineCollider(colliderId).HitTestBasic(ref collEvent, ref state.InsideOfs, in ball, + ball.CollisionEvent.HitTime, false, false, false); + + case ColliderType.Flipper: + ref var flipperState = ref state.GetFlipperState(colliderId); + return Colliders.GetFlipperCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, ref flipperState.Hit, + in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, in ball, collEvent.HitTime); + + case ColliderType.Plunger: + ref var plungerState = ref state.GetPlungerState(colliderId); + return Colliders.GetPlungerCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, ref plungerState.Movement, + in plungerState.Collider, in plungerState.Static, in ball, collEvent.HitTime); + } + return -1f; + } + + private bool IsInactiveDropTarget(int colliderId) + { + ref var coll = ref Colliders.Value.Colliders[colliderId].Value; + if (coll.ItemType == ItemType.HitTarget && HasDropTargetState(colliderId)) { + ref var dropTargetState = ref GetDropTargetState(colliderId); + if (dropTargetState.Animation.IsDropped || dropTargetState.Animation.MoveAnimation) { // QUICKFIX so that DT is not triggered twice + return true; + } + } + return false; + } + + #endregion } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index a12626995..bd1752af8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -35,10 +35,9 @@ ref PhysicsState state for (var i = 0; i < overlappingColliders.Length; i++) { var newCollEvent = new CollisionEventData(); - var colliderRef = new ColliderRef(overlappingColliders[i], ref state.Colliders); - var newTime = colliderRef.HitTest(ref ball, ref newCollEvent, ref contacts, ref state); - SaveCollisions(ref ball, ref newCollEvent, ref contacts, colliderRef.Id, newTime); - } + var newTime = state.HitTest(overlappingColliders[i], ref ball, ref newCollEvent, ref contacts, ref state); + SaveCollisions(ref ball, ref newCollEvent, ref contacts, overlappingColliders[i], newTime); + } // no negative time allowed if (ball.CollisionEvent.HitTime < 0) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs deleted file mode 100644 index d1b9fa5ac..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs +++ /dev/null @@ -1,110 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Collections; -using Unity.Entities; -using VisualPinball.Engine.VPT; - -namespace VisualPinball.Unity -{ - public readonly ref struct ColliderRef - { - internal readonly int Id; - private readonly BlobAssetReference _colliders; - - internal ColliderRef(int id, ref BlobAssetReference colliders) - { - _colliders = colliders; - Id = id; - } - - internal float HitTest(ref BallData ball, ref CollisionEventData collEvent, ref NativeList contacts, ref PhysicsState state) - { - if (IsInactiveDropTarget(ref state)) { - return -1f; - } - switch (_colliders.GetType(Id)) { - case ColliderType.Bumper: - case ColliderType.Circle: - return _colliders.GetCircleCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, - ball.CollisionEvent.HitTime); - - case ColliderType.Gate: - return _colliders.GetGateCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, - ball.CollisionEvent.HitTime); - - case ColliderType.Line: - return _colliders.GetLineCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, - ball.CollisionEvent.HitTime); - - case ColliderType.LineZ: - return _colliders.GetLineZCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); - - case ColliderType.Line3D: - return _colliders.GetLine3DCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); - - case ColliderType.LineSlingShot: - return _colliders.GetLineSlingshotCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); - - case ColliderType.Point: - return _colliders.GetPointCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); - - case ColliderType.Plane: - return _colliders.GetPlaneCollider(Id).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); - - case ColliderType.Spinner: - return _colliders.GetSpinnerCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, in ball, - ball.CollisionEvent.HitTime); - - case ColliderType.Triangle: - return _colliders.GetTriangleCollider(Id).HitTest(ref collEvent, in state.InsideOfs, in ball, - ball.CollisionEvent.HitTime); - - case ColliderType.KickerCircle: - case ColliderType.TriggerCircle: - return _colliders.GetCircleCollider(Id).HitTestBasicRadius(ref collEvent, ref state.InsideOfs, in ball, - ball.CollisionEvent.HitTime, false, false, false); - - case ColliderType.TriggerLine: - return _colliders.GetLineCollider(Id).HitTestBasic(ref collEvent, ref state.InsideOfs, in ball, - ball.CollisionEvent.HitTime, false, false, false); - - case ColliderType.Flipper: - ref var flipperState = ref state.GetFlipperState(Id); - return _colliders.GetFlipperCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, ref flipperState.Hit, - in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, in ball, collEvent.HitTime); - - case ColliderType.Plunger: - ref var plungerState = ref state.GetPlungerState(Id); - return _colliders.GetPlungerCollider(Id).HitTest(ref collEvent, ref state.InsideOfs, ref plungerState.Movement, - in plungerState.Collider, in plungerState.Static, in ball, collEvent.HitTime); - } - return -1f; - } - - private bool IsInactiveDropTarget(ref PhysicsState state) - { - ref var coll = ref _colliders.Value.Colliders[Id].Value; - if (coll.ItemType == ItemType.HitTarget && state.HasDropTargetState(Id)) { - ref var dropTargetState = ref state.GetDropTargetState(Id); - if (dropTargetState.Animation.IsDropped || dropTargetState.Animation.MoveAnimation) { // QUICKFIX so that DT is not triggered twice - return true; - } - } - return false; - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs.meta deleted file mode 100644 index 3ef6fabbf..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderRef.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 9dae49cec2cb490bbe02e99f758ceaca -timeCreated: 1696112308 \ No newline at end of file From 4e6d7802e67bd8523a5e95350bea05cdf9c91ed1 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 8 Oct 2023 01:16:13 +0200 Subject: [PATCH 068/159] jobs: Pass struct instead of List to collider generators. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 11 +- .../Physics/Collider/ColliderReference.cs | 103 +++++++++++++++ .../Collider/ColliderReference.cs.meta | 3 + .../Physics/Collider/ColliderUtils.cs | 8 +- .../Collision/ColliderAllocationJob.cs | 45 ++----- .../Physics/Collision/QuadTreeCreator.cs | 103 +++++++-------- .../VPT/Bumper/BumperApi.cs | 2 +- .../VisualPinball.Unity/VPT/CollidableApi.cs | 6 +- .../VPT/ColliderComponent.cs | 119 +++++++----------- .../VPT/Flipper/FlipperApi.cs | 2 +- .../VisualPinball.Unity/VPT/Gate/GateApi.cs | 4 +- .../VPT/Gate/GateColliderGenerator.cs | 14 +-- .../VPT/HitTarget/DropTargetApi.cs | 4 +- .../HitTarget/DropTargetColliderGenerator.cs | 2 +- .../VPT/HitTarget/HitTargetApi.cs | 4 +- .../HitTarget/HitTargetColliderGenerator.cs | 4 +- .../VPT/HitTarget/TargetColliderGenerator.cs | 2 +- .../VisualPinball.Unity/VPT/IApi.cs | 2 +- .../VPT/ICollidableComponent.cs | 2 +- .../VPT/Kicker/KickerApi.cs | 2 +- .../VPT/MetalWireGuide/MetalWireGuideApi.cs | 4 +- .../MetalWireGuideColliderGenerator.cs | 10 +- .../VPT/Playfield/PlayfieldApi.cs | 4 +- .../VPT/Plunger/PlungerApi.cs | 2 +- .../VPT/Primitive/PrimitiveApi.cs | 4 +- .../Primitive/PrimitiveColliderGenerator.cs | 4 +- .../VisualPinball.Unity/VPT/Ramp/RampApi.cs | 4 +- .../VPT/Ramp/RampColliderGenerator.cs | 22 ++-- .../VPT/Rubber/RubberApi.cs | 4 +- .../VPT/Rubber/RubberColliderGenerator.cs | 10 +- .../VPT/Spinner/SpinnerApi.cs | 4 +- .../VPT/Spinner/SpinnerColliderGenerator.cs | 6 +- .../VPT/Surface/SurfaceApi.cs | 4 +- .../VPT/Surface/SurfaceColliderGenerator.cs | 10 +- .../VPT/Trigger/TriggerApi.cs | 4 +- .../VPT/Trigger/TriggerColliderGenerator.cs | 16 +-- 36 files changed, 307 insertions(+), 247 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 92f46bf0a..467878439 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -95,14 +95,13 @@ private void Start() var sw = Stopwatch.StartNew(); var colliderItems = GetComponentsInChildren(); Debug.Log($"Found {colliderItems.Length} collidable items."); - var managedColliders = new List(); + var colliders = new ColliderReference(Allocator.TempJob); foreach (var colliderItem in colliderItems) { - // todo bring GC allocations down - colliderItem.GetColliders(player, managedColliders, 0); + colliderItem.GetColliders(player, ref colliders, 0); } // allocate colliders - _colliders = AllocateColliders(managedColliders); + _colliders = AllocateColliders(ref colliders); // create octree var elapsedMs = sw.Elapsed.TotalMilliseconds; @@ -131,9 +130,9 @@ private void Start() _physicsEnv[0] = env; } - private static BlobAssetReference AllocateColliders(IEnumerable managedColliders) + private static BlobAssetReference AllocateColliders(ref ColliderReference managedColliders) { - var allocateColliderJob = new ColliderAllocationJob(managedColliders); + var allocateColliderJob = new ColliderAllocationJob(ref managedColliders); allocateColliderJob.Run(); var colliders = allocateColliderJob.BlobAsset[0]; allocateColliderJob.Dispose(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs new file mode 100644 index 000000000..ac133c56b --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs @@ -0,0 +1,103 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Collections.Generic; +using System.Linq; +using Unity.Collections; + +namespace VisualPinball.Unity +{ + public struct ColliderReference : IDisposable + { + internal NativeList CircleColliders; + internal NativeList FlipperColliders; + internal NativeList GateColliders; + internal NativeList Line3DColliders; + internal NativeList LineSlingshotColliders; + internal NativeList LineColliders; + internal NativeList LineZColliders; + internal NativeList PlungerColliders; + internal NativeList PointColliders; + internal NativeList SpinnerColliders; + internal NativeList TriangleColliders; + internal NativeList PlaneColliders; + + public ColliderReference(Allocator allocator) + { + CircleColliders = new NativeList(allocator); + FlipperColliders = new NativeList(allocator); + GateColliders = new NativeList(allocator); + Line3DColliders = new NativeList(allocator); + LineSlingshotColliders = new NativeList(allocator); + LineColliders = new NativeList(allocator); + LineZColliders = new NativeList(allocator); + PlungerColliders = new NativeList(allocator); + PointColliders = new NativeList(allocator); + SpinnerColliders = new NativeList(allocator); + TriangleColliders = new NativeList(allocator); + PlaneColliders = new NativeList(allocator); + } + + public void Dispose() + { + CircleColliders.Dispose(); + FlipperColliders.Dispose(); + GateColliders.Dispose(); + Line3DColliders.Dispose(); + LineSlingshotColliders.Dispose(); + LineColliders.Dispose(); + LineZColliders.Dispose(); + PlungerColliders.Dispose(); + PointColliders.Dispose(); + SpinnerColliders.Dispose(); + TriangleColliders.Dispose(); + PlaneColliders.Dispose(); + } + + internal List All { + get { + var list = new List(); + list.AddRange(CircleColliders.Select(c => (ICollider)c)); + list.AddRange(FlipperColliders.Select(c => (ICollider)c)); + list.AddRange(GateColliders.Select(c => (ICollider)c)); + list.AddRange(Line3DColliders.Select(c => (ICollider)c)); + list.AddRange(LineSlingshotColliders.Select(c => (ICollider)c)); + list.AddRange(LineColliders.Select(c => (ICollider)c)); + list.AddRange(LineZColliders.Select(c => (ICollider)c)); + list.AddRange(PlungerColliders.Select(c => (ICollider)c)); + list.AddRange(PointColliders.Select(c => (ICollider)c)); + list.AddRange(SpinnerColliders.Select(c => (ICollider)c)); + list.AddRange(TriangleColliders.Select(c => (ICollider)c)); + list.AddRange(PlaneColliders.Select(c => (ICollider)c)); + return list; + } + } + + internal void Add(CircleCollider collider) => CircleColliders.Add(collider); + internal void Add(FlipperCollider collider) => FlipperColliders.Add(collider); + internal void Add(GateCollider collider) => GateColliders.Add(collider); + internal void Add(Line3DCollider collider) => Line3DColliders.Add(collider); + internal void Add(LineSlingshotCollider collider) => LineSlingshotColliders.Add(collider); + internal void Add(LineCollider collider) => LineColliders.Add(collider); + internal void Add(LineZCollider collider) => LineZColliders.Add(collider); + internal void Add(PlungerCollider collider) => PlungerColliders.Add(collider); + internal void Add(PointCollider collider) => PointColliders.Add(collider); + internal void Add(SpinnerCollider collider) => SpinnerColliders.Add(collider); + internal void Add(TriangleCollider collider) => TriangleColliders.Add(collider); + internal void Add(PlaneCollider collider) => PlaneColliders.Add(collider); + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs.meta new file mode 100644 index 000000000..62c4aa785 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9444b66c84164b8c9db3a671b943ea03 +timeCreated: 1696717952 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs index 852cd2775..2e9dc6cd2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs @@ -28,7 +28,7 @@ public static class ColliderUtils { private static readonly ProfilerMarker PerfMarker1 = new("ColliderUtils.GenerateCollidersFromMesh"); - public static void Generate3DPolyColliders(in float3[] rgv, ColliderInfo info, ICollection colliders) + public static void Generate3DPolyColliders(in float3[] rgv, ColliderInfo info, ref ColliderReference colliders) { var inputVerts = new float2[rgv.Length]; @@ -46,10 +46,10 @@ public static void Generate3DPolyColliders(in float3[] rgv, ColliderInfo info, I } var mesh = new Mesh(triangulatedVerts, outputIndices); - GenerateCollidersFromMesh(mesh, info, colliders, true); + GenerateCollidersFromMesh(mesh, info, ref colliders, true); } - public static void GenerateCollidersFromMesh(Mesh mesh, ColliderInfo info, ICollection colliders, bool onlyTriangles = false) + public static void GenerateCollidersFromMesh(Mesh mesh, ColliderInfo info, ref ColliderReference colliders, bool onlyTriangles = false) { PerfMarker1.Begin(); var addedEdges = EdgeSet.Get(); @@ -91,7 +91,7 @@ public static void GenerateCollidersFromMesh(Mesh mesh, ColliderInfo info, IColl PerfMarker1.End(); } - public static void GenerateCollidersFromMesh(in NativeArray vertices, in NativeArray indices, ref Matrix4x4 matrix, ColliderInfo info, ICollection colliders, bool onlyTriangles = false) + public static void GenerateCollidersFromMesh(in NativeArray vertices, in NativeArray indices, ref Matrix4x4 matrix, ColliderInfo info, ref ColliderReference colliders, bool onlyTriangles = false) { PerfMarker1.Begin(); var addedEdges = EdgeSet.Get(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs index fe24c73cd..1e8824365 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using System; -using System.Collections.Generic; using Unity.Burst; using Unity.Collections; using Unity.Entities; @@ -59,44 +58,26 @@ internal struct ColliderAllocationJob : IJob, IDisposable /// public NativeArray> BlobAsset; - public ColliderAllocationJob(IEnumerable colliderList) : this() + public ColliderAllocationJob(ref ColliderReference colliderList) : this() { var perfMarker = new ProfilerMarker("ColliderAllocationJob.ctr"); perfMarker.Begin(); - _circleColliders = new NativeList(Allocator.TempJob); - _flipperColliders = new NativeList(Allocator.TempJob); - _gateColliders = new NativeList(Allocator.TempJob); - _line3DColliders = new NativeList(Allocator.TempJob); - _lineSlingshotColliders = new NativeList(Allocator.TempJob); - _lineColliders = new NativeList(Allocator.TempJob); - _lineZColliders = new NativeList(Allocator.TempJob); - _plungerColliders = new NativeList(Allocator.TempJob); - _pointColliders = new NativeList(Allocator.TempJob); - _spinnerColliders = new NativeList(Allocator.TempJob); - _triangleColliders = new NativeList(Allocator.TempJob); - _planeColliders = new NativeList(Allocator.TempJob); + _circleColliders = colliderList.CircleColliders; + _flipperColliders = colliderList.FlipperColliders; + _gateColliders = colliderList.GateColliders; + _line3DColliders = colliderList.Line3DColliders; + _lineSlingshotColliders = colliderList.LineSlingshotColliders; + _lineColliders = colliderList.LineColliders; + _lineZColliders = colliderList.LineZColliders; + _plungerColliders = colliderList.PlungerColliders; + _pointColliders = colliderList.PointColliders; + _spinnerColliders = colliderList.SpinnerColliders; + _triangleColliders = colliderList.TriangleColliders; + _planeColliders = colliderList.PlaneColliders; BlobAsset = new NativeArray>(1, Allocator.Persistent); - // separate created colliders per type - foreach (var collider in colliderList) { - switch (collider) { - case CircleCollider circleCollider: _circleColliders.Add(circleCollider); break; - case FlipperCollider flipperCollider: _flipperColliders.Add(flipperCollider); break; - case GateCollider gateCollider: _gateColliders.Add(gateCollider); break; - case LineCollider lineCollider: _lineColliders.Add(lineCollider); break; - case Line3DCollider line3DCollider: _line3DColliders.Add(line3DCollider); break; - case LineSlingshotCollider lineSlingshotCollider: _lineSlingshotColliders.Add(lineSlingshotCollider); break; - case LineZCollider lineZCollider: _lineZColliders.Add(lineZCollider); break; - case PlaneCollider planeCollider: _planeColliders.Add(planeCollider); break; - case PlungerCollider plungerCollider: _plungerColliders.Add(plungerCollider); break; - case PointCollider pointCollider: _pointColliders.Add(pointCollider); break; - case SpinnerCollider spinnerCollider: _spinnerColliders.Add(spinnerCollider); break; - case TriangleCollider triangleCollider: _triangleColliders.Add(triangleCollider); break; - } - } - perfMarker.End(); } public void Execute() diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs index f1916916d..fbac9ab37 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs @@ -40,57 +40,58 @@ public static void Create(EntityManager entityManager, out NativeHashMap(); - var playfieldComponent = player.GetComponentInChildren(); - var itemApis = player.ColliderGenerators.ToArray(); - - // 1. generate colliders - PerfMarkerGenerateColliders.Begin(); - var colliderList = new List(); - //var (playfieldCollider, glassCollider) = player.PlayfieldApi.CreateColliders(0); - itemsColliding = new NativeHashMap(itemApis.Length, Allocator.Persistent); - foreach (var itemApi in itemApis) { - // fixme job - // PerfMarkerCreateColliders.Begin(); - // if (itemApi.ColliderEntity != Entity.Null) { - // itemsColliding.Add(itemApi.ColliderEntity, itemApi.IsColliderEnabled); - // } - // itemApi.CreateColliders(colliderList, 0); - // PerfMarkerCreateColliders.End(); - } - PerfMarkerGenerateColliders.End(); - - // 2. allocate created colliders - PerfMarkerCreateBlobAsset.Begin(); - var allocateColliderJob = new ColliderAllocationJob(colliderList/*, playfieldCollider, glassCollider*/); - allocateColliderJob.Run(); - - // retrieve result and dispose - var colliderBlobAssetRef = allocateColliderJob.BlobAsset[0]; - allocateColliderJob.Dispose(); - PerfMarkerCreateBlobAsset.End(); - - // 3. Create quadtree blob (BlobAssetReference) from AABBs - PerfMarkerCreateQuadTree.Begin(); - BlobAssetReference quadTreeBlobAssetRef; - using (var builder = new BlobBuilder(Allocator.Temp)) { - ref var rootQuadTree = ref builder.ConstructRoot(); - QuadTree.Create(builder, ref colliderBlobAssetRef.Value.Colliders, ref rootQuadTree.QuadTree, - playfieldComponent.BoundingBox.ToAabb()); - - quadTreeBlobAssetRef = builder.CreateBlobAssetReference(Allocator.Persistent); - } - PerfMarkerCreateQuadTree.End(); - - // save it to entity - PerfMarkerSaveToEntity.Begin(); - //Debug.Log(quadTreeBlobAssetRef.Value.QuadTree.ToString(0)); - var collEntity = entityManager.CreateEntity(ComponentType.ReadOnly(), ComponentType.ReadOnly()); - entityManager.SetComponentData(collEntity, new QuadTreeData { Value = quadTreeBlobAssetRef }); - entityManager.SetComponentData(collEntity, new ColliderData { Value = colliderBlobAssetRef }); - PerfMarkerSaveToEntity.End(); - - Logger.Info("Static QuadTree initialized."); + // var player = Object.FindObjectOfType(); + // var playfieldComponent = player.GetComponentInChildren(); + // var itemApis = player.ColliderGenerators.ToArray(); + // + // // 1. generate colliders + // PerfMarkerGenerateColliders.Begin(); + // var colliderList = new List(); + // //var (playfieldCollider, glassCollider) = player.PlayfieldApi.CreateColliders(0); + // itemsColliding = new NativeHashMap(itemApis.Length, Allocator.Persistent); + itemsColliding = new NativeHashMap(0, Allocator.Persistent); + // foreach (var itemApi in itemApis) { + // // fixme job + // // PerfMarkerCreateColliders.Begin(); + // // if (itemApi.ColliderEntity != Entity.Null) { + // // itemsColliding.Add(itemApi.ColliderEntity, itemApi.IsColliderEnabled); + // // } + // // itemApi.CreateColliders(colliderList, 0); + // // PerfMarkerCreateColliders.End(); + // } + // PerfMarkerGenerateColliders.End(); + // + // // 2. allocate created colliders + // PerfMarkerCreateBlobAsset.Begin(); + // var allocateColliderJob = new ColliderAllocationJob(colliderList/*, playfieldCollider, glassCollider*/); + // allocateColliderJob.Run(); + // + // // retrieve result and dispose + // var colliderBlobAssetRef = allocateColliderJob.BlobAsset[0]; + // allocateColliderJob.Dispose(); + // PerfMarkerCreateBlobAsset.End(); + // + // // 3. Create quadtree blob (BlobAssetReference) from AABBs + // PerfMarkerCreateQuadTree.Begin(); + // BlobAssetReference quadTreeBlobAssetRef; + // using (var builder = new BlobBuilder(Allocator.Temp)) { + // ref var rootQuadTree = ref builder.ConstructRoot(); + // QuadTree.Create(builder, ref colliderBlobAssetRef.Value.Colliders, ref rootQuadTree.QuadTree, + // playfieldComponent.BoundingBox.ToAabb()); + // + // quadTreeBlobAssetRef = builder.CreateBlobAssetReference(Allocator.Persistent); + // } + // PerfMarkerCreateQuadTree.End(); + // + // // save it to entity + // PerfMarkerSaveToEntity.Begin(); + // //Debug.Log(quadTreeBlobAssetRef.Value.QuadTree.ToString(0)); + // var collEntity = entityManager.CreateEntity(ComponentType.ReadOnly(), ComponentType.ReadOnly()); + // entityManager.SetComponentData(collEntity, new QuadTreeData { Value = quadTreeBlobAssetRef }); + // entityManager.SetComponentData(collEntity, new ColliderData { Value = colliderBlobAssetRef }); + // PerfMarkerSaveToEntity.End(); + // + // Logger.Info("Static QuadTree initialized."); PerfMarkerTotal.End(); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs index 591985c0d..5cbff8dd4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs @@ -73,7 +73,7 @@ void IApiCoil.OnCoil(bool enabled) protected override bool FireHitEvents => ColliderComponent.HitEvent; protected override float HitThreshold => ColliderComponent.Threshold; - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var height = MainComponent.PositionZ; colliders.Add(new CircleCollider(MainComponent.Position, MainComponent.Radius, height, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs index b088ea9dc..86b2c75cb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs @@ -64,14 +64,14 @@ protected CollidableApi(GameObject go, Player player) : base(go, player) protected virtual bool FireHitEvents => false; protected virtual float HitThreshold => 0; - protected abstract void CreateColliders(List colliders, float margin); + protected abstract void CreateColliders(ref ColliderReference colliders, float margin); - void IApiColliderGenerator.CreateColliders(List colliders, float margin) + void IApiColliderGenerator.CreateColliders(ref ColliderReference colliders, float margin) { if (!ColliderComponent) { return; } - CreateColliders(colliders, margin); + CreateColliders(ref colliders, margin); } ColliderInfo IApiColliderGenerator.GetColliderInfo() => GetColliderInfo(MainComponent.ItemType); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index 417d9eabf..cde84193f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -127,31 +127,33 @@ private void OnDrawGizmos() var generateColliders = ShowAabbs || showColliders && !HasCachedColliders; if (generateColliders) { var api = InstantiateColliderApi(player); - var colliders = new List(); - api.CreateColliders(colliders, 0.1f); + var colliders = new ColliderReference(Allocator.TempJob); + api.CreateColliders(ref colliders, 0.1f); if (showColliders) { - _colliderMesh = GenerateColliderMesh(colliders); + _colliderMesh = GenerateColliderMesh(ref colliders); _collidersDirty = false; } if (ShowAabbs) { - for (var i = 0; i < colliders.Count; i++) { - var col = colliders[i]; + var colliderList = colliders.All; + for (var i = 0; i < colliderList.Count; i++) { + var col = colliderList[i]; DrawAabb(col.Bounds.Aabb, i == SelectedCollider); } } + colliders.Dispose(); } if (ShowColliderOctree) { var api = InstantiateColliderApi(player); - var colliders = new List(); - api.CreateColliders(colliders, 0.1f); + var colliders = new ColliderReference(Allocator.TempJob); + api.CreateColliders(ref colliders, 0.1f); var playfieldBounds = GetComponentInChildren().Bounds; var octree = new NativeOctree(playfieldBounds, 32, 10, Allocator.Persistent); - var allocateColliderJob = new ColliderAllocationJob(colliders); + var allocateColliderJob = new ColliderAllocationJob(ref colliders); allocateColliderJob.Run(); var colliderBlob = allocateColliderJob.BlobAsset[0]; allocateColliderJob.Dispose(); @@ -163,6 +165,7 @@ private void OnDrawGizmos() populateJob.Run(); Gizmos.color = Color.yellow; octree.DrawGizmos(); + colliders.Dispose(); } if (showColliders) { @@ -187,7 +190,7 @@ private void OnDrawGizmos() #region Collider Gizmos - private Mesh GenerateColliderMesh(List colliders) + private Mesh GenerateColliderMesh(ref ColliderReference colliders) { var color = Color.green; UnityEditor.Handles.color = color; @@ -197,69 +200,39 @@ private Mesh GenerateColliderMesh(List colliders) var normals = new List(); var indices = new List(); _nonMeshColliders.Clear(); - foreach (var col in colliders) { - switch (col) { - - case CircleCollider circleCol: { - AddCollider(circleCol, vertices, normals, indices); - break; - } - - case FlipperCollider _: { - AddFlipperCollider(vertices, normals, indices); - break; - } - - case GateCollider gateCol: { - AddCollider(gateCol.LineSeg0, vertices, normals, indices); - AddCollider(gateCol.LineSeg1, vertices, normals, indices); - break; - } - - case Line3DCollider line3DCol: { - // todo - break; - } - - case LineCollider lineCol: { - AddCollider(lineCol, vertices, normals, indices); - break; - } - - case LineSlingshotCollider lineSlingshotCol: { - AddCollider(lineSlingshotCol, vertices, normals, indices); - break; - } - - case LineZCollider lineZCol: { - _nonMeshColliders.Add(lineZCol); - break; - } - - case PlungerCollider plungerCol: { - AddCollider(plungerCol.LineSegBase, vertices, normals, indices); - AddCollider(plungerCol.JointBase0, vertices, normals, indices); - AddCollider(plungerCol.JointBase1, vertices, normals, indices); - break; - } - - case PointCollider pointCol: { - // ignoring points for now - break; - } - - case SpinnerCollider spinnerCol: { - AddCollider(spinnerCol.LineSeg0, vertices, normals, indices); - AddCollider(spinnerCol.LineSeg1, vertices, normals, indices); - break; - } - - case TriangleCollider triangleCol: { - AddCollider(triangleCol, vertices, normals, indices); - break; - } - } + foreach (var col in colliders.CircleColliders) { + AddCollider(col, vertices, normals, indices); + } + foreach (var _ in colliders.FlipperColliders) { + AddFlipperCollider(vertices, normals, indices); + } + foreach (var col in colliders.GateColliders) { + AddCollider(col.LineSeg0, vertices, normals, indices); + AddCollider(col.LineSeg1, vertices, normals, indices); + } + foreach (var col in colliders.LineColliders) { + AddCollider(col, vertices, normals, indices); + } + foreach (var col in colliders.LineSlingshotColliders) { + AddCollider(col, vertices, normals, indices); } + foreach (var col in colliders.LineZColliders) { + _nonMeshColliders.Add(col); + } + foreach (var col in colliders.PlungerColliders) { + AddCollider(col.LineSegBase, vertices, normals, indices); + AddCollider(col.JointBase0, vertices, normals, indices); + AddCollider(col.JointBase1, vertices, normals, indices); + } + foreach (var col in colliders.SpinnerColliders) { + AddCollider(col.LineSeg0, vertices, normals, indices); + AddCollider(col.LineSeg1, vertices, normals, indices); + } + foreach (var col in colliders.TriangleColliders) { + AddCollider(col, vertices, normals, indices); + } + + // todo Line3DCollider return new Mesh { name = $"{name} (debug collider)", @@ -457,9 +430,9 @@ private static void DrawAabb(Aabb aabb, bool isSelected) #endregion - void ICollidableComponent.GetColliders(Player player, List colliders, float margin) + void ICollidableComponent.GetColliders(Player player, ref ColliderReference colliders, float margin) { - InstantiateColliderApi(player).CreateColliders(colliders, margin); + InstantiateColliderApi(player).CreateColliders(ref colliders, margin); } #endif } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs index 4a5ec50ca..f519892e1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs @@ -218,7 +218,7 @@ void IApiCollidable.OnCollide(int ballId, float hit) #region Collider Generation - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var height = MainComponent.PositionZ; var baseRadius = math.max(MainComponent.BaseRadius, 0.01f); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs index 3fae7c340..1938f31ff 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs @@ -99,10 +99,10 @@ public void Lift(float speed, float angleDeg) #region Collider Generation - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var colliderGenerator = new GateColliderGenerator(this, MainComponent, ColliderComponent); - colliderGenerator.GenerateColliders(MainComponent.PositionZ, colliders); + colliderGenerator.GenerateColliders(MainComponent.PositionZ, ref colliders); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderGenerator.cs index 0f01a0a90..8e00197f2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderGenerator.cs @@ -35,7 +35,7 @@ internal GateColliderGenerator(GateApi gateApi, IGateData data, IGateColliderDat _collData = collData; } - internal void GenerateColliders(float height, List colliders) // var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y); + internal void GenerateColliders(float height, ref ColliderReference colliders) // var height = table.GetSurfaceHeight(_data.Surface, _data.Center.X, _data.Center.Y); { var angleMin = math.min(_collData.AngleMin, _collData.AngleMax); // correct angle inversions var angleMax = math.max(_collData.AngleMin, _collData.AngleMax); @@ -47,14 +47,14 @@ internal GateColliderGenerator(GateApi gateApi, IGateData data, IGateColliderDat var radAngle = math.radians(_data.Rotation); var tangent = new float2(math.cos(radAngle), math.sin(radAngle)); - GenerateGateCollider(colliders, height, radAngle); - GenerateLineCollider(colliders, height, tangent); + GenerateGateCollider(ref colliders, height, radAngle); + GenerateLineCollider(ref colliders, height, tangent); if (_data.ShowBracket) { - GenerateBracketColliders(colliders, height, tangent); + GenerateBracketColliders(ref colliders, height, tangent); } } - private void GenerateGateCollider(ICollection colliders, float height, float radAngle) + private void GenerateGateCollider(ref ColliderReference colliders, float height, float radAngle) { var halfLength = _data.Length * 0.5f; var sn = math.sin(radAngle); @@ -74,7 +74,7 @@ private void GenerateGateCollider(ICollection colliders, float height colliders.Add(new GateCollider(in lineSeg0, in lineSeg1, _api.GetColliderInfo())); } - private void GenerateLineCollider(ICollection colliders, float height, float2 tangent) + private void GenerateLineCollider(ref ColliderReference colliders, float height, float2 tangent) { if (_collData.TwoWay) { return; @@ -90,7 +90,7 @@ private void GenerateLineCollider(ICollection colliders, float height colliders.Add(new LineCollider(rgv0, rgv1, height, height + 2.0f * PhysicsConstants.PhysSkin, info)); //!! = ball diameter } - private void GenerateBracketColliders(ICollection colliders, float height, float2 tangent) + private void GenerateBracketColliders(ref ColliderReference colliders, float height, float2 tangent) { var center = new float2(_data.PosX, _data.PosY); var halfLength = _data.Length * 0.5f; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs index 24b4b15b7..5ad342965 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs @@ -105,10 +105,10 @@ private void SetIsDropped(bool isDropped) protected override bool FireHitEvents => true; protected override float HitThreshold => ColliderComponent.Threshold; - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var colliderGenerator = new DropTargetColliderGenerator(this, MainComponent, MainComponent); - colliderGenerator.GenerateColliders(MainComponent.PlayfieldHeight, colliders); + colliderGenerator.GenerateColliders(MainComponent.PlayfieldHeight, ref colliders); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderGenerator.cs index 97c2cf3ce..95a109e31 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderGenerator.cs @@ -28,7 +28,7 @@ public DropTargetColliderGenerator(IApiColliderGenerator api, ITargetData data, { } - internal void GenerateColliders(float playfieldHeight, ICollection colliders) + internal void GenerateColliders(float playfieldHeight, ref ColliderReference colliders) { var localToPlayfield = MeshGenerator.GetTransformationMatrix(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs index 53f27b3a4..b0b6542f1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs @@ -59,10 +59,10 @@ internal HitTargetApi(GameObject go, Player player) : base(go, player) protected override bool FireHitEvents => true; protected override float HitThreshold => ColliderComponent.Threshold; - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var colliderGenerator = new HitTargetColliderGenerator(this, MainComponent, MainComponent); - colliderGenerator.GenerateColliders(colliders); + colliderGenerator.GenerateColliders(ref colliders); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderGenerator.cs index eeaa082df..c50c7d86b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderGenerator.cs @@ -26,7 +26,7 @@ public HitTargetColliderGenerator(IApiColliderGenerator api, ITargetData data, I { } - internal void GenerateColliders(List colliders) + internal void GenerateColliders(ref ColliderReference colliders) { var localToPlayfield = MeshGenerator.GetTransformationMatrix(); var hitMesh = MeshGenerator.GetMesh(); @@ -34,7 +34,7 @@ internal void GenerateColliders(List colliders) hitMesh.Vertices[i].MultiplyMatrix(localToPlayfield); } var addedEdges = EdgeSet.Get(); - GenerateCollidables(hitMesh, addedEdges, true, colliders); + GenerateCollidables(hitMesh, addedEdges, true, ref colliders); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetColliderGenerator.cs index 91eefacc4..1946601c6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetColliderGenerator.cs @@ -33,7 +33,7 @@ protected TargetColliderGenerator(IApiColliderGenerator api, ITargetData data, I MeshGenerator = meshGenerator; } - private protected void GenerateCollidables(Mesh hitMesh, EdgeSet addedEdges, bool setHitObject, ICollection colliders) { + private protected void GenerateCollidables(Mesh hitMesh, EdgeSet addedEdges, bool setHitObject, ref ColliderReference colliders) { // add the normal drop target as collidable but without hit event for (var i = 0; i < hitMesh.Indices.Length; i += 3) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs index 1eea5f548..db467a1e8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs @@ -44,7 +44,7 @@ public interface IApiColliderGenerator ///
/// List to add colliders to. /// - void CreateColliders(List colliders, float margin); + void CreateColliders(ref ColliderReference colliders, float margin); /// /// Computes collider info based on the component data. diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs index e7a6ed9b0..091f2a35d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs @@ -20,6 +20,6 @@ namespace VisualPinball.Unity { public interface ICollidableComponent { - internal void GetColliders(Player player, List colliders, float margin); + internal void GetColliders(Player player, ref ColliderReference colliders, float margin); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs index 39a8fccb2..0dde647a0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs @@ -250,7 +250,7 @@ private void KickXYZ(int kickerId, float angle, float speed, float inclination, #region Collider Generation - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var height = MainComponent.PositionZ; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs index 55a0afe67..d9054bca5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs @@ -43,10 +43,10 @@ internal MetalWireGuideApi(GameObject go, Player player) : base(go, player) protected override bool FireHitEvents => ColliderComponent.HitEvent; protected override float HitThreshold => 2.0f; // hard coded threshold for now - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var colliderGenerator = new MetalWireGuideColliderGenerator(this, new MetalWireGuideMeshGenerator(MainComponent)); - colliderGenerator.GenerateColliders(MainComponent.PlayfieldHeight, ColliderComponent.HitHeight, MainComponent.Bendradius, MainComponent.PlayfieldDetailLevel, colliders, margin); + colliderGenerator.GenerateColliders(MainComponent.PlayfieldHeight, ColliderComponent.HitHeight, MainComponent.Bendradius, MainComponent.PlayfieldDetailLevel, ref colliders, margin); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderGenerator.cs index f974ddbdb..6535f0b0d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderGenerator.cs @@ -31,7 +31,7 @@ public MetalWireGuideColliderGenerator(MetalWireGuideApi metalWireGuideApi, Meta _meshGenerator = meshGenerator; } - internal void GenerateColliders(float playfieldHeight, float hitHeight, float bendradius, int detailLevel, List colliders, float margin) + internal void GenerateColliders(float playfieldHeight, float hitHeight, float bendradius, int detailLevel, ref ColliderReference colliders, float margin) { var mesh = _meshGenerator.GetTransformedMesh(playfieldHeight, hitHeight, detailLevel, bendradius, 6, true, margin); //!! adapt hacky code in the function if changing the "6" here var addedEdges = EdgeSet.Get(); @@ -45,9 +45,9 @@ internal void GenerateColliders(float playfieldHeight, float hitHeight, float be colliders.Add(new TriangleCollider(rg0, rg1, rg2, _api.GetColliderInfo())); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i], mesh.Indices[i + 2], colliders); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 2], mesh.Indices[i + 1], colliders); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 1], mesh.Indices[i], colliders); + GenerateHitEdge(mesh, addedEdges, mesh.Indices[i], mesh.Indices[i + 2], ref colliders); + GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 2], mesh.Indices[i + 1], ref colliders); + GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 1], mesh.Indices[i], ref colliders); } // add collision vertices @@ -57,7 +57,7 @@ internal void GenerateColliders(float playfieldHeight, float hitHeight, float be } private void GenerateHitEdge(Mesh mesh, EdgeSet addedEdges, int i, int j, - ICollection colliders) + ref ColliderReference colliders) { if (addedEdges.ShouldAddHitEdge(i, j)) { var v1 = mesh.Vertices[i].ToUnityFloat3(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs index 6357d66ba..e306e846a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs @@ -31,7 +31,7 @@ internal PlayfieldApi(GameObject go, Player player) : base(go, player) #region Collider Generation - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var info = ((IApiColliderGenerator)this).GetColliderInfo(); var planeColliderInfo = new ColliderInfo { @@ -54,7 +54,7 @@ protected override void CreateColliders(List colliders, float margin) if (meshComp && !meshComp.AutoGenerate) { var mf = GameObject.GetComponent(); if (mf && mf.sharedMesh) { - ColliderUtils.GenerateCollidersFromMesh(mf.sharedMesh.ToVpMesh().TransformToVpx(), info, colliders); + ColliderUtils.GenerateCollidersFromMesh(mf.sharedMesh.ToVpMesh().TransformToVpx(), info, ref colliders); } else { Debug.LogWarning($"Could not find mesh filter on playfield {GameObject.name}"); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs index 9f9b53c4e..7ab6f5504 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs @@ -157,7 +157,7 @@ private IApiCoil Coil(string deviceItem) #region Collider Generation - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { colliders.Add(new PlungerCollider(MainComponent, ColliderComponent, GetColliderInfo())); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs index dff33ec5b..9325eef5d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs @@ -43,10 +43,10 @@ internal PrimitiveApi(GameObject go, Player player) : base(go, player) protected override bool FireHitEvents => ColliderComponent.HitEvent; protected override float HitThreshold => ColliderComponent.Threshold; - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var colliderGenerator = new PrimitiveColliderGenerator(this, MainComponent, MainComponent); - colliderGenerator.GenerateColliders(ColliderComponent.CollisionReductionFactor, colliders); + colliderGenerator.GenerateColliders(ColliderComponent.CollisionReductionFactor, ref colliders); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderGenerator.cs index ac637f12c..1d11db365 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderGenerator.cs @@ -51,7 +51,7 @@ public PrimitiveColliderGenerator(IApiColliderGenerator primitiveApi, IMeshGener _primitiveComponent = primitiveComponent; } - internal void GenerateColliders(float collisionReductionFactor, List colliders) + internal void GenerateColliders(float collisionReductionFactor, ref ColliderReference colliders) { PerfMarker1.Begin(); //var mesh = _meshGenerator.GetMesh(); @@ -92,7 +92,7 @@ internal void GenerateColliders(float collisionReductionFactor, List PerfMarker3.Begin(); var worldToVpx = _meshGenerator.GetTransformationMatrix().TransformToVpx().ToUnityMatrix(); - ColliderUtils.GenerateCollidersFromMesh(in unityVertices, in unityIndices, ref worldToVpx, _api.GetColliderInfo(), colliders); + ColliderUtils.GenerateCollidersFromMesh(in unityVertices, in unityIndices, ref worldToVpx, _api.GetColliderInfo(), ref colliders); PerfMarker3.End(); PerfMarker1.End(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs index b5bbfa660..6ad1a87b0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs @@ -61,10 +61,10 @@ void IApi.OnDestroy() protected override bool FireHitEvents => ColliderComponent.HitEvent; protected override float HitThreshold => ColliderComponent.Threshold; - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var colliderGenerator = new RampColliderGenerator(this, MainComponent, ColliderComponent); - colliderGenerator.GenerateColliders(MainComponent.PlayfieldHeight, colliders, margin); + colliderGenerator.GenerateColliders(MainComponent.PlayfieldHeight, ref colliders, margin); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderGenerator.cs index f2214b7ef..1c6c5b543 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderGenerator.cs @@ -38,7 +38,7 @@ public RampColliderGenerator(RampApi rampApi, IRampData data, RampColliderCompon _meshGenerator = new RampMeshGenerator(data); } - internal void GenerateColliders(float tableHeight, List colliders, float margin = 0f) + internal void GenerateColliders(float tableHeight, ref ColliderReference colliders, float margin = 0f) { var rv = _meshGenerator.GetRampVertex(tableHeight, PhysicsConstants.HitShapeDetailLevel, true); var rgvLocal = rv.RgvLocal; @@ -58,9 +58,9 @@ internal void GenerateColliders(float tableHeight, List colliders, fl pv3 = rgvLocal[i + 1].ToUnityFloat2(); GenerateWallLineSeg(pv2, pv3, i > 0,rgHeight1[i], - rgHeight1[i + 1], wallHeightRight, colliders); + rgHeight1[i + 1], wallHeightRight, ref colliders); GenerateWallLineSeg(pv3, pv2, i < vertexCount - 2, rgHeight1[i], - rgHeight1[i + 1], wallHeightRight, colliders); + rgHeight1[i + 1], wallHeightRight, ref colliders); // add joints at start and end of right wall if (i == 0) { @@ -82,9 +82,9 @@ internal void GenerateColliders(float tableHeight, List colliders, fl pv3 = rgvLocal[vertexCount + i + 1].ToUnityFloat2(); GenerateWallLineSeg(pv2, pv3, i > 0, rgHeight1[vertexCount - i - 2], - rgHeight1[vertexCount - i - 1], wallHeightLeft, colliders); + rgHeight1[vertexCount - i - 1], wallHeightLeft, ref colliders); GenerateWallLineSeg(pv3, pv2, i < vertexCount - 2, rgHeight1[vertexCount - i - 2], - rgHeight1[vertexCount - i - 1], wallHeightLeft, colliders); + rgHeight1[vertexCount - i - 1], wallHeightLeft, ref colliders); // add joints at start and end of left wall if (i == 0) { @@ -135,7 +135,7 @@ internal void GenerateColliders(float tableHeight, List colliders, fl var ph3dPoly = new TriangleCollider(rg0, rg1, rg2, _api.GetColliderInfo()); colliders.Add(ph3dPoly); - CheckJoint(isOldSet, in ph3dPolyOld, in ph3dPoly, colliders); + CheckJoint(isOldSet, in ph3dPolyOld, in ph3dPoly, ref colliders); ph3dPolyOld = ph3dPoly; isOldSet = true; } @@ -152,7 +152,7 @@ internal void GenerateColliders(float tableHeight, List colliders, fl var ph3dPoly = new TriangleCollider(rg0, rg1, rg2, _api.GetColliderInfo()); colliders.Add(ph3dPoly); - CheckJoint(isOldSet, in ph3dPolyOld, in ph3dPoly, colliders); + CheckJoint(isOldSet, in ph3dPolyOld, in ph3dPoly, ref colliders); ph3dPolyOld = ph3dPoly; isOldSet = true; } @@ -211,14 +211,14 @@ private float2 GetWallHeights() } private void GenerateWallLineSeg(float2 pv1, float2 pv2, bool pv3Exists, float height1, float height2, float wallHeight, - ICollection colliders) + ref ColliderReference colliders) { //!! Hit-walls are still done via 2D line segments with only a single lower and upper border, so the wall will always reach below and above the actual ramp -between- two points of the ramp // Thus, subdivide until at some point the approximation error is 'subtle' enough so that one will usually not notice (i.e. dependent on ball size) if (height2 - height1 > 2.0 * PhysicsConstants.PhysSkin) { //!! use ballsize - GenerateWallLineSeg(pv1, (pv1 + pv2) * 0.5f, pv3Exists, height1, (height1 + height2) * 0.5f, wallHeight, colliders); + GenerateWallLineSeg(pv1, (pv1 + pv2) * 0.5f, pv3Exists, height1, (height1 + height2) * 0.5f, wallHeight, ref colliders); - GenerateWallLineSeg((pv1 + pv2) * 0.5f, pv2, true, (height1 + height2) * 0.5f, height2, wallHeight, colliders); + GenerateWallLineSeg((pv1 + pv2) * 0.5f, pv2, true, (height1 + height2) * 0.5f, height2, wallHeight, ref colliders); } else { colliders.Add(new LineCollider(pv1, pv2, height1, height2 + wallHeight, @@ -231,7 +231,7 @@ private void GenerateWallLineSeg(float2 pv1, float2 pv2, bool pv3Exists, float h } private void CheckJoint(bool isOldSet, in TriangleCollider ph3d1, in TriangleCollider ph3d2, - ICollection colliders) + ref ColliderReference colliders) { if (isOldSet) { // may be null in case of degenerate triangles var jointNormal = math.cross(ph3d1.Normal(), ph3d2.Normal()); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs index 6586a5c05..564c4d9c3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs @@ -43,10 +43,10 @@ internal RubberApi(GameObject go, Player player) : base(go, player) protected override bool FireHitEvents => ColliderComponent.HitEvent; protected override float HitThreshold => 2.0f; // hard coded threshold for now - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var colliderGenerator = new RubberColliderGenerator(this, new RubberMeshGenerator(MainComponent)); - colliderGenerator.GenerateColliders(MainComponent.PlayfieldHeight, ColliderComponent.HitHeight, MainComponent.PlayfieldDetailLevel, colliders, margin); + colliderGenerator.GenerateColliders(MainComponent.PlayfieldHeight, ColliderComponent.HitHeight, MainComponent.PlayfieldDetailLevel, ref colliders, margin); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderGenerator.cs index 8142ae59b..5ca7debec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderGenerator.cs @@ -31,7 +31,7 @@ public RubberColliderGenerator(RubberApi rubberApi, RubberMeshGenerator meshGene _meshGenerator = meshGenerator; } - internal void GenerateColliders(float playfieldHeight, float hitHeight, int detailLevel, List colliders, float margin) + internal void GenerateColliders(float playfieldHeight, float hitHeight, int detailLevel, ref ColliderReference colliders, float margin) { var mesh = _meshGenerator.GetTransformedMesh(playfieldHeight, hitHeight, detailLevel, 6, true, margin); //!! adapt hacky code in the function if changing the "6" here var addedEdges = EdgeSet.Get(); @@ -45,9 +45,9 @@ internal void GenerateColliders(float playfieldHeight, float hitHeight, int deta colliders.Add(new TriangleCollider(rg0, rg1, rg2, _api.GetColliderInfo())); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i], mesh.Indices[i + 2], colliders); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 2], mesh.Indices[i + 1], colliders); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 1], mesh.Indices[i], colliders); + GenerateHitEdge(mesh, addedEdges, mesh.Indices[i], mesh.Indices[i + 2], ref colliders); + GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 2], mesh.Indices[i + 1], ref colliders); + GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 1], mesh.Indices[i], ref colliders); } // add collision vertices @@ -57,7 +57,7 @@ internal void GenerateColliders(float playfieldHeight, float hitHeight, int deta } private void GenerateHitEdge(Mesh mesh, EdgeSet addedEdges, int i, int j, - ICollection colliders) + ref ColliderReference colliders) { if (addedEdges.ShouldAddHitEdge(i, j)) { var v1 = mesh.Vertices[i].ToUnityFloat3(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs index 0ea616146..554d09988 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs @@ -84,10 +84,10 @@ public SpinnerApi(GameObject go, Player player) : base(go, player) protected override bool FireHitEvents => true; - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var colliderGenerator = new SpinnerColliderGenerator(this, MainComponent); - colliderGenerator.GenerateColliders(MainComponent.HeightOnPlayfield, colliders); + colliderGenerator.GenerateColliders(MainComponent.HeightOnPlayfield, ref colliders); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderGenerator.cs index 859528890..edd7f5dbb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderGenerator.cs @@ -30,15 +30,15 @@ public SpinnerColliderGenerator(SpinnerApi spinnerApi, SpinnerComponent componen _component = component; } - internal void GenerateColliders(float height, List colliders) + internal void GenerateColliders(float height, ref ColliderReference colliders) { colliders.Add(new SpinnerCollider(_component, height - _component.Height, _api.GetColliderInfo())); if (_component.ShowBracket) { - GenerateBracketColliders(height, colliders); + GenerateBracketColliders(height, ref colliders); } } - private void GenerateBracketColliders(float height, ICollection colliders) + private void GenerateBracketColliders(float height, ref ColliderReference colliders) { const float h = 30.0f; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs index d63125844..e9c90ebc4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs @@ -47,13 +47,13 @@ internal SurfaceApi(GameObject go, Player player) : base(go, player) protected override bool FireHitEvents => true; protected override float HitThreshold => ColliderComponent.Threshold; - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { if (MainComponent.DragPoints.Length == 0) { return; } var colliderGenerator = new SurfaceColliderGenerator(this, MainComponent, ColliderComponent); - colliderGenerator.GenerateColliders(MainComponent.PlayfieldHeight, colliders, margin); + colliderGenerator.GenerateColliders(MainComponent.PlayfieldHeight, ref colliders, margin); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderGenerator.cs index 565d05dab..4c1ec83d9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderGenerator.cs @@ -35,7 +35,7 @@ public SurfaceColliderGenerator(SurfaceApi surfaceApi, SurfaceComponent componen _colliderComponent = colliderComponent; } - internal void GenerateColliders(float playfieldHeight, List colliders, float margin = 0f) + internal void GenerateColliders(float playfieldHeight, ref ColliderReference colliders, float margin = 0f) { var vVertex = DragPoint.GetRgVertex(_component.DragPoints); @@ -56,20 +56,20 @@ internal void GenerateColliders(float playfieldHeight, List colliders var pv2 = vVertex[(i + 1) % count]; var pv3 = vVertex[(i + 2) % count]; - GenerateLinePolys(pv2, pv3, playfieldHeight, colliders); + GenerateLinePolys(pv2, pv3, playfieldHeight, ref colliders); } - ColliderUtils.Generate3DPolyColliders(in rgv3Dt, _api.GetColliderInfo(), colliders); + ColliderUtils.Generate3DPolyColliders(in rgv3Dt, _api.GetColliderInfo(), ref colliders); if (rgv3Db != null) { - ColliderUtils.Generate3DPolyColliders(in rgv3Db, _api.GetColliderInfo(), colliders); + ColliderUtils.Generate3DPolyColliders(in rgv3Db, _api.GetColliderInfo(), ref colliders); } } /// /// Returns the hit line polygons for the surface. /// - private void GenerateLinePolys(RenderVertex2D pv1, Vertex2D pv2, float playfieldHeight, ICollection colliders) + private void GenerateLinePolys(RenderVertex2D pv1, Vertex2D pv2, float playfieldHeight, ref ColliderReference colliders) { var bottom = _component.HeightBottom + playfieldHeight; var top = _component.HeightTop + playfieldHeight; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs index d509836f2..8f61dc3bb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs @@ -64,12 +64,12 @@ internal TriggerApi(GameObject go, Player player) protected override bool FireHitEvents => true; - protected override void CreateColliders(List colliders, float margin) + protected override void CreateColliders(ref ColliderReference colliders, float margin) { var meshComponent = GameObject.GetComponent(); if (meshComponent) { var colliderGenerator = new TriggerColliderGenerator(this, MainComponent, ColliderComponent, meshComponent); - colliderGenerator.GenerateColliders(colliders); + colliderGenerator.GenerateColliders(ref colliders); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderGenerator.cs index 867b1ef80..5aaa7abe2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderGenerator.cs @@ -39,24 +39,24 @@ public TriggerColliderGenerator(TriggerApi triggerApi, TriggerComponent componen _colliderComponent = colliderComponent; } - internal void GenerateColliders(List colliders) + internal void GenerateColliders(ref ColliderReference colliders) { if (IsRound) { - GenerateRoundHitObjects(colliders); + GenerateRoundHitObjects(ref colliders); } else { - GenerateCurvedHitObjects(colliders); + GenerateCurvedHitObjects(ref colliders); } } - private void GenerateRoundHitObjects(ICollection colliders) + private void GenerateRoundHitObjects(ref ColliderReference colliders) { var height = _component.PositionZ; colliders.Add(new CircleCollider(_component.Center, _colliderComponent.HitCircleRadius, height, height + _colliderComponent.HitHeight, _api.GetColliderInfo(), ColliderType.TriggerCircle)); } - private void GenerateCurvedHitObjects(ICollection colliders) + private void GenerateCurvedHitObjects(ref ColliderReference colliders) { var height = _component.PositionZ; var vVertex = DragPoint.GetRgVertex(_component.DragPoints); @@ -69,16 +69,16 @@ private void GenerateCurvedHitObjects(ICollection colliders) rgv[i] = vVertex[i]; rgv3D[i] = new float3(rgv[i].X, rgv[i].Y, height + (float)(PhysicsConstants.PhysSkin * 2.0)); } - ColliderUtils.Generate3DPolyColliders(rgv3D, _api.GetColliderInfo(), colliders); + ColliderUtils.Generate3DPolyColliders(rgv3D, _api.GetColliderInfo(), ref colliders); for (var i = 0; i < count; i++) { var pv2 = rgv[i < count - 1 ? i + 1 : 0]; var pv3 = rgv[i < count - 2 ? i + 2 : i + 2 - count]; - AddLineSeg(pv2.ToUnityFloat2(), pv3.ToUnityFloat2(), height, colliders); + AddLineSeg(pv2.ToUnityFloat2(), pv3.ToUnityFloat2(), height, ref colliders); } } - private void AddLineSeg(float2 pv1, float2 pv2, float height, ICollection colliders) { + private void AddLineSeg(float2 pv1, float2 pv2, float height, ref ColliderReference colliders) { colliders.Add(new LineCollider(pv1, pv2, height, height + math.max(_colliderComponent.HitHeight - 8.0f, 0f), _api.GetColliderInfo(), ColliderType.TriggerLine)); } From c942733b2cbe8d29ebcd834ef7caeb646b970a42 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 8 Oct 2023 12:45:46 +0200 Subject: [PATCH 069/159] jobs: Don't allocate edge sets when creating primitive mesh. --- .../VisualPinball.Unity/Common/EdgeSet.cs | 22 +++++++++++-------- .../Physics/Collider/ColliderUtils.cs | 15 ++++++++----- .../HitTarget/DropTargetColliderGenerator.cs | 5 ++++- .../HitTarget/HitTargetColliderGenerator.cs | 6 +++-- .../VPT/HitTarget/TargetColliderGenerator.cs | 2 +- .../MetalWireGuideColliderGenerator.cs | 13 ++++++----- .../VPT/Rubber/RubberColliderGenerator.cs | 13 ++++++----- 7 files changed, 47 insertions(+), 29 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Common/EdgeSet.cs b/VisualPinball.Unity/VisualPinball.Unity/Common/EdgeSet.cs index 206def19b..0a550c182 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Common/EdgeSet.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Common/EdgeSet.cs @@ -14,22 +14,24 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System.Collections.Generic; +using System; +using Unity.Collections; +using Unity.Mathematics; namespace VisualPinball.Unity { - internal class EdgeSet + internal struct EdgeSet : IDisposable { - private readonly HashSet _edges; + private NativeParallelHashSet _edges; - internal static EdgeSet Get() + internal static EdgeSet Get(Allocator allocator) { - return new EdgeSet(); + return new EdgeSet(allocator); } - private EdgeSet() + private EdgeSet(Allocator allocator) { - _edges = new HashSet(); + _edges = new NativeParallelHashSet(64, allocator); } private void Add(int i, int j) { @@ -48,9 +50,11 @@ internal bool ShouldAddHitEdge(int i, int j) { return false; } - private static long GetKey(int i, int j) + private static long GetKey(int i, int j) => ((long) math.min(i, j) << 32) + math.max(i, j); + + public void Dispose() { - return ((long) System.Math.Min(i, j) << 32) + System.Math.Max(i, j); + _edges.Dispose(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs index 2e9dc6cd2..755e8b9a9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System.Collections.Generic; using Unity.Collections; using Unity.Mathematics; using Unity.Profiling; @@ -26,7 +25,8 @@ namespace VisualPinball.Unity { public static class ColliderUtils { - private static readonly ProfilerMarker PerfMarker1 = new("ColliderUtils.GenerateCollidersFromMesh"); + private static readonly ProfilerMarker PerfMarker1 = new("ColliderUtils.GenerateCollidersFromMesh.ICollider"); + private static readonly ProfilerMarker PerfMarker2 = new("ColliderUtils.GenerateCollidersFromMesh.NativeArray"); public static void Generate3DPolyColliders(in float3[] rgv, ColliderInfo info, ref ColliderReference colliders) { @@ -52,7 +52,7 @@ public static void Generate3DPolyColliders(in float3[] rgv, ColliderInfo info, r public static void GenerateCollidersFromMesh(Mesh mesh, ColliderInfo info, ref ColliderReference colliders, bool onlyTriangles = false) { PerfMarker1.Begin(); - var addedEdges = EdgeSet.Get(); + var addedEdges = EdgeSet.Get(Allocator.TempJob); // add collision triangles and edges for (var i = 0; i < mesh.Indices.Length; i += 3) { @@ -81,6 +81,7 @@ public static void GenerateCollidersFromMesh(Mesh mesh, ColliderInfo info, ref C } } } + addedEdges.Dispose(); // add collision vertices if (!onlyTriangles) { @@ -93,8 +94,8 @@ public static void GenerateCollidersFromMesh(Mesh mesh, ColliderInfo info, ref C public static void GenerateCollidersFromMesh(in NativeArray vertices, in NativeArray indices, ref Matrix4x4 matrix, ColliderInfo info, ref ColliderReference colliders, bool onlyTriangles = false) { - PerfMarker1.Begin(); - var addedEdges = EdgeSet.Get(); + PerfMarker2.Begin(); + var addedEdges = EdgeSet.Get(Allocator.TempJob); // add collision triangles and edges for (var i = 0; i < indices.Length; i += 3) { @@ -129,7 +130,9 @@ public static void GenerateCollidersFromMesh(in NativeArray vertices, i colliders.Add(new PointCollider(matrix.MultiplyPoint(vertex), info)); } } - PerfMarker1.End(); + + addedEdges.Dispose(); + PerfMarker2.End(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderGenerator.cs index 95a109e31..bf07c0cee 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderGenerator.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System.Collections.Generic; +using Unity.Collections; using Unity.Mathematics; using VisualPinball.Engine.Math; using VisualPinball.Engine.VPT; @@ -43,7 +44,7 @@ internal void GenerateColliders(float playfieldHeight, ref ColliderReference col GenerateCollidables(hitMesh, addedEdges, Data.IsLegacy, colliders); */ - var addedEdges = EdgeSet.Get(); + var addedEdges = EdgeSet.Get(Allocator.TempJob); var tempMatrix = new Matrix3D().RotateZMatrix(MathF.DegToRad(Data.RotZ)); var fullMatrix = new Matrix3D().Multiply(tempMatrix); @@ -108,6 +109,8 @@ internal void GenerateColliders(float playfieldHeight, ref ColliderReference col colliders.Add(new PointCollider(rgv3D[i].ToUnityFloat3(), GetColliderInfo(true))); } } + + addedEdges.Dispose(); } private static readonly float3[] DropTargetHitPlaneVertices = { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderGenerator.cs index c50c7d86b..d7eb3b77c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderGenerator.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System.Collections.Generic; +using Unity.Collections; using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.HitTarget; @@ -33,8 +34,9 @@ internal void GenerateColliders(ref ColliderReference colliders) for (var i = 0; i < hitMesh.Vertices.Length; i++) { hitMesh.Vertices[i].MultiplyMatrix(localToPlayfield); } - var addedEdges = EdgeSet.Get(); - GenerateCollidables(hitMesh, addedEdges, true, ref colliders); + var addedEdges = EdgeSet.Get(Allocator.TempJob); + GenerateCollidables(hitMesh, ref addedEdges, true, ref colliders); + addedEdges.Dispose(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetColliderGenerator.cs index 1946601c6..c1120b01a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetColliderGenerator.cs @@ -33,7 +33,7 @@ protected TargetColliderGenerator(IApiColliderGenerator api, ITargetData data, I MeshGenerator = meshGenerator; } - private protected void GenerateCollidables(Mesh hitMesh, EdgeSet addedEdges, bool setHitObject, ref ColliderReference colliders) { + private protected void GenerateCollidables(Mesh hitMesh, ref EdgeSet addedEdges, bool setHitObject, ref ColliderReference colliders) { // add the normal drop target as collidable but without hit event for (var i = 0; i < hitMesh.Indices.Length; i += 3) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderGenerator.cs index 6535f0b0d..070b35499 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderGenerator.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System.Collections.Generic; +using Unity.Collections; using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.MetalWireGuide; @@ -34,7 +35,7 @@ public MetalWireGuideColliderGenerator(MetalWireGuideApi metalWireGuideApi, Meta internal void GenerateColliders(float playfieldHeight, float hitHeight, float bendradius, int detailLevel, ref ColliderReference colliders, float margin) { var mesh = _meshGenerator.GetTransformedMesh(playfieldHeight, hitHeight, detailLevel, bendradius, 6, true, margin); //!! adapt hacky code in the function if changing the "6" here - var addedEdges = EdgeSet.Get(); + var addedEdges = EdgeSet.Get(Allocator.TempJob); // add collision triangles and edges for (var i = 0; i < mesh.Indices.Length; i += 3) { @@ -45,18 +46,20 @@ internal void GenerateColliders(float playfieldHeight, float hitHeight, float be colliders.Add(new TriangleCollider(rg0, rg1, rg2, _api.GetColliderInfo())); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i], mesh.Indices[i + 2], ref colliders); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 2], mesh.Indices[i + 1], ref colliders); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 1], mesh.Indices[i], ref colliders); + GenerateHitEdge(mesh, ref addedEdges, mesh.Indices[i], mesh.Indices[i + 2], ref colliders); + GenerateHitEdge(mesh, ref addedEdges, mesh.Indices[i + 2], mesh.Indices[i + 1], ref colliders); + GenerateHitEdge(mesh, ref addedEdges, mesh.Indices[i + 1], mesh.Indices[i], ref colliders); } // add collision vertices foreach (var mv in mesh.Vertices) { colliders.Add(new PointCollider(mv.ToUnityFloat3(), _api.GetColliderInfo())); } + + addedEdges.Dispose(); } - private void GenerateHitEdge(Mesh mesh, EdgeSet addedEdges, int i, int j, + private void GenerateHitEdge(Mesh mesh, ref EdgeSet addedEdges, int i, int j, ref ColliderReference colliders) { if (addedEdges.ShouldAddHitEdge(i, j)) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderGenerator.cs index 5ca7debec..f5786261b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderGenerator.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System.Collections.Generic; +using Unity.Collections; using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.Rubber; @@ -34,7 +35,7 @@ public RubberColliderGenerator(RubberApi rubberApi, RubberMeshGenerator meshGene internal void GenerateColliders(float playfieldHeight, float hitHeight, int detailLevel, ref ColliderReference colliders, float margin) { var mesh = _meshGenerator.GetTransformedMesh(playfieldHeight, hitHeight, detailLevel, 6, true, margin); //!! adapt hacky code in the function if changing the "6" here - var addedEdges = EdgeSet.Get(); + var addedEdges = EdgeSet.Get(Allocator.TempJob); // add collision triangles and edges for (var i = 0; i < mesh.Indices.Length; i += 3) { @@ -45,18 +46,20 @@ internal void GenerateColliders(float playfieldHeight, float hitHeight, int deta colliders.Add(new TriangleCollider(rg0, rg1, rg2, _api.GetColliderInfo())); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i], mesh.Indices[i + 2], ref colliders); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 2], mesh.Indices[i + 1], ref colliders); - GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 1], mesh.Indices[i], ref colliders); + GenerateHitEdge(mesh, ref addedEdges, mesh.Indices[i], mesh.Indices[i + 2], ref colliders); + GenerateHitEdge(mesh, ref addedEdges, mesh.Indices[i + 2], mesh.Indices[i + 1], ref colliders); + GenerateHitEdge(mesh, ref addedEdges, mesh.Indices[i + 1], mesh.Indices[i], ref colliders); } // add collision vertices foreach (var mv in mesh.Vertices) { colliders.Add(new PointCollider(mv.ToUnityFloat3(), _api.GetColliderInfo())); } + + addedEdges.Dispose(); } - private void GenerateHitEdge(Mesh mesh, EdgeSet addedEdges, int i, int j, + private void GenerateHitEdge(Mesh mesh, ref EdgeSet addedEdges, int i, int j, ref ColliderReference colliders) { if (addedEdges.ShouldAddHitEdge(i, j)) { From 2e3581acf883ec282c8abfed3db5026d7cb5583c Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 8 Oct 2023 13:21:29 +0200 Subject: [PATCH 070/159] jobs: Init hashmap with correct capacity. --- VisualPinball.Unity/VisualPinball.Unity/Common/EdgeSet.cs | 8 ++++---- .../VisualPinball.Unity/Physics/Collider/ColliderUtils.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Common/EdgeSet.cs b/VisualPinball.Unity/VisualPinball.Unity/Common/EdgeSet.cs index 0a550c182..eaab41fbc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Common/EdgeSet.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Common/EdgeSet.cs @@ -24,14 +24,14 @@ internal struct EdgeSet : IDisposable { private NativeParallelHashSet _edges; - internal static EdgeSet Get(Allocator allocator) + internal static EdgeSet Get(Allocator allocator, int capacity = 1024) { - return new EdgeSet(allocator); + return new EdgeSet(allocator, capacity); } - private EdgeSet(Allocator allocator) + private EdgeSet(Allocator allocator, int capacity) { - _edges = new NativeParallelHashSet(64, allocator); + _edges = new NativeParallelHashSet(capacity, allocator); } private void Add(int i, int j) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs index 755e8b9a9..b452e50d2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderUtils.cs @@ -95,7 +95,7 @@ public static void GenerateCollidersFromMesh(Mesh mesh, ColliderInfo info, ref C public static void GenerateCollidersFromMesh(in NativeArray vertices, in NativeArray indices, ref Matrix4x4 matrix, ColliderInfo info, ref ColliderReference colliders, bool onlyTriangles = false) { PerfMarker2.Begin(); - var addedEdges = EdgeSet.Get(Allocator.TempJob); + var addedEdges = EdgeSet.Get(Allocator.TempJob, vertices.Length); // add collision triangles and edges for (var i = 0; i < indices.Length; i += 3) { From 299a418c2f2039c5c901b0bcd121f57de7e3c13d Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 8 Oct 2023 22:07:38 +0200 Subject: [PATCH 071/159] jobs: Add gate displacement. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 15 +- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 13 +- .../VPT/Gate/GateComponent.cs | 3 +- .../VPT/Gate/GateDisplacementPhysics.cs | 103 +++++++++++++ ...s.meta => GateDisplacementPhysics.cs.meta} | 0 .../VPT/Gate/GateDisplacementSystem.cs | 144 ------------------ .../VPT/Gate/GateMovementSystem.cs | 54 ------- .../VPT/Gate/GateMovementSystem.cs.meta | 11 -- 8 files changed, 129 insertions(+), 214 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/{GateDisplacementSystem.cs.meta => GateDisplacementPhysics.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 74a9e1eec..78eba3355 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -87,17 +87,26 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) #region Displacement PerfMarkerDisplacement.Begin(); - // displacement + // balls using (var enumerator = state.Balls.GetEnumerator()) { while (enumerator.MoveNext()) { BallDisplacementPhysics.UpdateDisplacements(ref enumerator.Current.Value, hitTime); // use static method instead of member } } - + // flippers using (var enumerator = state.FlipperStates.GetEnumerator()) { while (enumerator.MoveNext()) { ref var flipperState = ref enumerator.Current.Value; - FlipperDisplacementPhysics.UpdateDisplacement(flipperState.ItemId, ref flipperState.Movement, ref flipperState.Tricks, in flipperState.Static, hitTime, ref state.EventQueue); + FlipperDisplacementPhysics.UpdateDisplacement(flipperState.ItemId, ref flipperState.Movement, + ref flipperState.Tricks, in flipperState.Static, hitTime, ref state.EventQueue); + } + } + // gates + using (var enumerator = state.GateStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var gateState = ref enumerator.Current.Value; + GateDisplacementPhysics.UpdateDisplacement(gateState.ItemId, ref gateState.Movement, in gateState.Static, + hitTime, ref state.EventQueue); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 467878439..b3a7e824c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -25,6 +25,7 @@ using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Common; +using VisualPinball.Unity.Collections; using VisualPinballUnity; using Debug = UnityEngine.Debug; @@ -197,8 +198,9 @@ private void Update() // flippers using (var enumerator = _flipperStates.GetEnumerator()) { while (enumerator.MoveNext()) { + ref var flipperState = ref enumerator.Current.Value; var flipperTransform = _transforms[enumerator.Current.Key]; - flipperTransform.localRotation = quaternion.Euler(0, _flipperStates[enumerator.Current.Key].Movement.Angle, 0); + flipperTransform.localRotation = quaternion.Euler(0, flipperState.Movement.Angle, 0); } } @@ -215,6 +217,15 @@ private void Update() } } + // gates + using (var enumerator = _gateStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var gateState = ref enumerator.Current.Value; + var gateTransform = _transforms[gateState.WireItemId]; + gateTransform.localRotation = quaternion.RotateX(-gateState.Movement.Angle); + } + } + #endregion } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs index 7a3d62f03..5bf40fc24 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs @@ -290,10 +290,11 @@ internal GateState CreateState() AngleMin = math.radians(collComponent._angleMin), AngleMax = math.radians(collComponent._angleMax), Height = Position.z, - Damping = math.pow(collComponent.Damping, (float)PhysicsConstants.PhysFactor), + Damping = math.pow(math.clamp(collComponent.Damping, 0, 1), (float)PhysicsConstants.PhysFactor), GravityFactor = collComponent.GravityFactor, TwoWay = collComponent.TwoWay, } : default; + Debug.Log($"Damping = {staticData.Damping}"); var wireComponent = GetComponentInChildren(); var movementData = collComponent && wireComponent diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs new file mode 100644 index 000000000..88249f45c --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs @@ -0,0 +1,103 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Collections; +using Unity.Mathematics; +using VisualPinball.Engine.Game; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class GateDisplacementPhysics + { + internal static void UpdateDisplacement(int itemId, ref GateMovementData movementData, in GateStaticData data, + float dTime, ref NativeQueue.ParallelWriter events) + { + if (data.TwoWay) { + if (math.abs(movementData.Angle) > data.AngleMax) { + if (movementData.Angle < 0.0) { + movementData.Angle = -data.AngleMax; + } else { + movementData.Angle = data.AngleMax; + } + + // send EOS event + events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, movementData.AngleSpeed)); + + if (!movementData.ForcedMove) { + movementData.AngleSpeed = -movementData.AngleSpeed; + movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + } else if (movementData.AngleSpeed > 0.0) { + movementData.AngleSpeed = 0.0f; + } + } + if (math.abs(movementData.Angle) < data.AngleMin) { + if (movementData.Angle < 0.0) { + movementData.Angle = -data.AngleMin; + } else { + movementData.Angle = data.AngleMin; + } + if (!movementData.ForcedMove) { + movementData.AngleSpeed = -movementData.AngleSpeed; + movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + } else if (movementData.AngleSpeed < 0.0) { + movementData.AngleSpeed = 0.0f; + } + } + } else { + var direction = movementData.HitDirection ? -1f : 1f; + if (direction * movementData.Angle > data.AngleMax) { + movementData.Angle = direction * data.AngleMax; + + // send EOS event + events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, movementData.AngleSpeed)); + + if (!movementData.ForcedMove) { + movementData.AngleSpeed = -movementData.AngleSpeed; + movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + } else if (movementData.AngleSpeed > 0.0) { + movementData.AngleSpeed = 0.0f; + } + } + if (direction * movementData.Angle < data.AngleMin) { + movementData.Angle = direction * data.AngleMin; + + // send Park event + events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, movementData.AngleSpeed)); + + if (!movementData.ForcedMove) { + movementData.AngleSpeed = -movementData.AngleSpeed; + movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + } else if (movementData.AngleSpeed < 0.0) { + movementData.AngleSpeed = 0.0f; + } + } + } + + movementData.Angle += movementData.AngleSpeed * dTime; + + if (movementData.IsLifting) { + if (math.abs(movementData.Angle - movementData.LiftAngle) > 0.000001f) { + var direction = movementData.Angle < movementData.LiftAngle ? 1f : -1f; + movementData.Angle += direction * (movementData.LiftSpeed * dTime); + + } else { + movementData.IsLifting = false; + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs deleted file mode 100644 index 4b6c53e14..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementSystem.cs +++ /dev/null @@ -1,144 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Collections; -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Engine.Game; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal partial class GateDisplacementSystem : SystemBaseStub - { - private Player _player; - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - private NativeQueue _eventQueue; - - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("GateDisplacementSystem"); - - protected override void OnCreate() - { - _player = Object.FindObjectOfType(); - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - _eventQueue = new NativeQueue(Allocator.Persistent); - } - - protected override void OnDestroy() - { - _eventQueue.Dispose(); - } - - protected override void OnUpdate() - { - var dTime = _simulateCycleSystemGroup.HitTime; - var marker = PerfMarker; - var events = _eventQueue.AsParallelWriter(); - - // fixme job - // Entities - // .WithName("GateDisplacementJob") - // .ForEach((Entity entity, ref GateMovementData movementData, in GateStaticData data) => { - // - // marker.Begin(); - // - // if (data.TwoWay) { - // if (math.abs(movementData.Angle) > data.AngleMax) { - // if (movementData.Angle < 0.0) { - // movementData.Angle = -data.AngleMax; - // } else { - // movementData.Angle = data.AngleMax; - // } - // - // // send EOS event - // events.Enqueue(new EventData(EventId.LimitEventsEos, entity, movementData.AngleSpeed)); - // - // if (!movementData.ForcedMove) { - // movementData.AngleSpeed = -movementData.AngleSpeed; - // movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - // } else if (movementData.AngleSpeed > 0.0) { - // movementData.AngleSpeed = 0.0f; - // } - // } - // if (math.abs(movementData.Angle) < data.AngleMin) { - // if (movementData.Angle < 0.0) { - // movementData.Angle = -data.AngleMin; - // } else { - // movementData.Angle = data.AngleMin; - // } - // if (!movementData.ForcedMove) { - // movementData.AngleSpeed = -movementData.AngleSpeed; - // movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - // } else if (movementData.AngleSpeed < 0.0) { - // movementData.AngleSpeed = 0.0f; - // } - // } - // } else { - // var direction = movementData.HitDirection ? -1f : 1f; - // if (direction * movementData.Angle > data.AngleMax) { - // movementData.Angle = direction * data.AngleMax; - // - // // send EOS event - // events.Enqueue(new EventData(EventId.LimitEventsEos, entity, movementData.AngleSpeed)); - // - // if (!movementData.ForcedMove) { - // movementData.AngleSpeed = -movementData.AngleSpeed; - // movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - // } else if (movementData.AngleSpeed > 0.0) { - // movementData.AngleSpeed = 0.0f; - // } - // } - // if (direction * movementData.Angle < data.AngleMin) { - // movementData.Angle = direction * data.AngleMin; - // - // // send Park event - // events.Enqueue(new EventData(EventId.LimitEventsBos, entity, movementData.AngleSpeed)); - // - // if (!movementData.ForcedMove) { - // movementData.AngleSpeed = -movementData.AngleSpeed; - // movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - // } else if (movementData.AngleSpeed < 0.0) { - // movementData.AngleSpeed = 0.0f; - // } - // } - // } - // movementData.Angle += movementData.AngleSpeed * dTime; - // - // if (movementData.IsLifting) { - // if (math.abs(movementData.Angle - movementData.LiftAngle) > 0.000001f) { - // var direction = movementData.Angle < movementData.LiftAngle ? 1f : -1f; - // movementData.Angle += direction * (movementData.LiftSpeed * dTime); - // - // } else { - // movementData.IsLifting = false; - // } - // } - // - // marker.End(); - // - // }).Run(); - - // dequeue events - while (_eventQueue.TryDequeue(out var eventData)) { - _player.OnEvent(in eventData); - } - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs deleted file mode 100644 index 2aa672637..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class GateMovementSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("GateMovementSystem"); - - private Player _player; - - protected override void OnStartRunning() - { - base.OnStartRunning(); - _player = Object.FindObjectOfType(); - } - - protected override void OnUpdate() - { - // fixme job - // var marker = PerfMarker; - // Entities.WithoutBurst().WithName("GateMovementJob").ForEach((Entity entity, in GateMovementData movementData) => { - // - // marker.Begin(); - // - // _player.GateWireTransforms[entity].localRotation = quaternion.RotateX(-movementData.Angle); - // - // marker.End(); - // - // }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs.meta deleted file mode 100644 index 6f112c9dc..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5fecec9bc1c0ce844853a4ab162a7dfd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 8e3b1e85c5beee8476550418a89c6ab60e0d72d7 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 8 Oct 2023 22:16:16 +0200 Subject: [PATCH 072/159] jobs: Add spinner displacement. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 8 ++ .../VisualPinball.Unity/Game/PhysicsEngine.cs | 9 ++ .../VPT/Spinner/SpinnerDisplacementPhysics.cs | 93 ++++++++++++ ...eta => SpinnerDisplacementPhysics.cs.meta} | 0 .../VPT/Spinner/SpinnerDisplacementSystem.cs | 135 ------------------ .../VPT/Spinner/SpinnerMovementSystem.cs | 54 ------- .../VPT/Spinner/SpinnerMovementSystem.cs.meta | 11 -- 7 files changed, 110 insertions(+), 200 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/{SpinnerDisplacementSystem.cs.meta => SpinnerDisplacementPhysics.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 78eba3355..52fade3d0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -109,6 +109,14 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) hitTime, ref state.EventQueue); } } + // spinners + using (var enumerator = state.SpinnerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var spinnerState = ref enumerator.Current.Value; + SpinnerDisplacementPhysics.UpdateDisplacement(spinnerState.ItemId, ref spinnerState.Movement, in spinnerState.Static, + hitTime, ref state.EventQueue); + } + } PerfMarkerDisplacement.End(); #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index b3a7e824c..beeda4557 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -226,6 +226,15 @@ private void Update() } } + // spinners + using (var enumerator = _spinnerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var spinnerState = ref enumerator.Current.Value; + var spinnerTransform = _transforms[spinnerState.AnimationItemId]; + spinnerTransform.localRotation = quaternion.RotateX(-spinnerState.Movement.Angle); + } + } + #endregion } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs new file mode 100644 index 000000000..f3ef752e0 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs @@ -0,0 +1,93 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable CompareOfFloatsByEqualityOperator + +using Unity.Collections; +using Unity.Mathematics; +using VisualPinball.Engine.Game; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class SpinnerDisplacementPhysics + { + internal static void UpdateDisplacement(int itemId, ref SpinnerMovementData movementData, in SpinnerStaticData data, + float dTime, ref NativeQueue.ParallelWriter events) + { + + // those are already converted to radian during authoring. + var angleMin = data.AngleMin; + var angleMax = data.AngleMax; + + // blocked spinner, limited motion spinner + if (data.AngleMin != data.AngleMax) { + + movementData.Angle += movementData.AngleSpeed * dTime; + + if (movementData.Angle > angleMax) { + movementData.Angle = angleMax; + + // send EOS event + events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, math.abs(math.degrees(movementData.AngleSpeed)))); + + if (movementData.AngleSpeed > 0.0f) { + movementData.AngleSpeed *= -0.005f - data.Elasticity; + } + } + + if (movementData.Angle < angleMin) { + movementData.Angle = angleMin; + + // send Park event + events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, math.abs(math.degrees(movementData.AngleSpeed)))); + + if (movementData.AngleSpeed < 0.0f) { + movementData.AngleSpeed *= -0.005f - data.Elasticity; + } + } + + } else { + + var target = movementData.AngleSpeed > 0.0f + ? movementData.Angle < math.PI ? math.PI : 3.0f * math.PI + : movementData.Angle < math.PI ? -math.PI : math.PI; + + movementData.Angle += movementData.AngleSpeed * dTime; + + if (movementData.AngleSpeed > 0.0f) { + + if (movementData.Angle > target) { + events.Enqueue(new EventData(EventId.SpinnerEventsSpin, itemId, true)); + } + + } else { + if (movementData.Angle < target) { + events.Enqueue(new EventData(EventId.SpinnerEventsSpin, itemId, true)); + } + } + + while (movementData.Angle > 2.0f * math.PI) { + movementData.Angle -= 2.0f * math.PI; + } + + while (movementData.Angle < 0.0f) { + movementData.Angle += 2.0f * math.PI; + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs deleted file mode 100644 index 157513325..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementSystem.cs +++ /dev/null @@ -1,135 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable CompareOfFloatsByEqualityOperator - -using Unity.Collections; -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Engine.Game; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal partial class SpinnerDisplacementSystem : SystemBaseStub - { - private Player _player; - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - private NativeQueue _eventQueue; - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("SpinnerDisplacementSystem"); - - protected override void OnCreate() - { - _player = Object.FindObjectOfType(); - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - _eventQueue = new NativeQueue(Allocator.Persistent); - } - - protected override void OnDestroy() - { - _eventQueue.Dispose(); - } - - protected override void OnUpdate() - { - - var events = _eventQueue.AsParallelWriter(); - - var dTime = _simulateCycleSystemGroup.HitTime; - var marker = PerfMarker; - - // fixme job - // Entities - // .WithName("SpinnerDisplacementJob") - // .ForEach((Entity entity, ref SpinnerMovementData movementData, in SpinnerStaticData data) => { - // - // marker.Begin(); - // - // // those are already converted to radian during authoring. - // var angleMin = data.AngleMin; - // var angleMax = data.AngleMax; - // - // // blocked spinner, limited motion spinner - // if (data.AngleMin != data.AngleMax) { - // - // movementData.Angle += movementData.AngleSpeed * dTime; - // - // if (movementData.Angle > angleMax) { - // movementData.Angle = angleMax; - // - // // send EOS event - // events.Enqueue(new EventData(EventId.LimitEventsEos, entity, math.abs(math.degrees(movementData.AngleSpeed)))); - // - // if (movementData.AngleSpeed > 0.0f) { - // movementData.AngleSpeed *= -0.005f - data.Elasticity; - // } - // } - // - // if (movementData.Angle < angleMin) { - // movementData.Angle = angleMin; - // - // // send Park event - // events.Enqueue(new EventData(EventId.LimitEventsBos, entity, math.abs(math.degrees(movementData.AngleSpeed)))); - // - // if (movementData.AngleSpeed < 0.0f) { - // movementData.AngleSpeed *= -0.005f - data.Elasticity; - // } - // } - // - // } else { - // - // var target = movementData.AngleSpeed > 0.0f - // ? movementData.Angle < math.PI ? math.PI : 3.0f * math.PI - // : movementData.Angle < math.PI ? -math.PI : math.PI; - // - // movementData.Angle += movementData.AngleSpeed * dTime; - // - // if (movementData.AngleSpeed > 0.0f) { - // - // if (movementData.Angle > target) { - // events.Enqueue(new EventData(EventId.SpinnerEventsSpin, entity, true)); - // } - // - // } else { - // if (movementData.Angle < target) { - // events.Enqueue(new EventData(EventId.SpinnerEventsSpin, entity, true)); - // } - // } - // - // while (movementData.Angle > 2.0f * math.PI) { - // movementData.Angle -= 2.0f * math.PI; - // } - // - // while (movementData.Angle < 0.0f) { - // movementData.Angle += 2.0f * math.PI; - // } - // } - // - // marker.End(); - // - // }).Run(); - - // dequeue events - while (_eventQueue.TryDequeue(out var eventData)) { - _player.OnEvent(in eventData); - } - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs deleted file mode 100644 index 8dcf0c339..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class SpinnerMovementSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("SpinnerMovementSystem"); - - private Player _player; - - protected override void OnStartRunning() - { - base.OnStartRunning(); - _player = Object.FindObjectOfType(); - } - - protected override void OnUpdate() - { - // fixme job - // var marker = PerfMarker; - // Entities.WithoutBurst().WithName("SpinnerMovementJob").ForEach((Entity entity, in SpinnerMovementData movementData) => { - // - // marker.Begin(); - // - // _player.SpinnerPlateTransforms[entity].localRotation = quaternion.RotateX(-movementData.Angle); - // - // marker.End(); - // - // }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs.meta deleted file mode 100644 index 5e077fb17..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 864f0b7730837de4aa013de0b2aecddb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 6dfe25261af33f2942e775b0b2e692f0045a9b85 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 8 Oct 2023 22:30:47 +0200 Subject: [PATCH 073/159] jobs: Add missing velocity physics. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 18 +++++- .../VPT/Gate/GateVelocityPhysics.cs | 42 +++++++++++++ ...em.cs.meta => GateVelocityPhysics.cs.meta} | 0 .../VPT/Gate/GateVelocitySystem.cs | 59 ------------------- ...itySystem.cs => SpinnerVelocityPhysics.cs} | 24 ++------ ...cs.meta => SpinnerVelocityPhysics.cs.meta} | 0 6 files changed, 64 insertions(+), 79 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/{GateVelocitySystem.cs.meta => GateVelocityPhysics.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/{SpinnerVelocitySystem.cs => SpinnerVelocityPhysics.cs} (55%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/{SpinnerVelocitySystem.cs.meta => SpinnerVelocityPhysics.cs.meta} (100%) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index beeda4557..5c1eb3bf7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -304,19 +304,35 @@ public void Execute() var timeMsec = (uint)((env.CurPhysicsFrameTime - env.StartTimeUsec) / 1000); var physicsDiffTime = (float)((env.NextPhysicsFrameTime - env.CurPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); + // update velocities - always on integral physics frame boundary (spinner, gate, flipper, plunger, ball) #region Update Velocities - // update velocities - always on integral physics frame boundary (spinner, gate, flipper, plunger, ball) + // balls using (var enumerator = state.Balls.GetEnumerator()) { while (enumerator.MoveNext()) { BallVelocityPhysics.UpdateVelocities(ref enumerator.Current.Value, env.Gravity); } } + // flippers using (var enumerator = FlipperStates.GetEnumerator()) { while (enumerator.MoveNext()) { FlipperVelocityPhysics.UpdateVelocities(ref enumerator.Current.Value); } } + // gates + using (var enumerator = GateStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var gateState = ref enumerator.Current.Value; + GateVelocityPhysics.UpdateVelocities(ref gateState.Movement, in gateState.Static); + } + } + // spinners + using (var enumerator = SpinnerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var spinnerState = ref enumerator.Current.Value; + SpinnerVelocityPhysics.UpdateVelocities(ref spinnerState.Movement, in spinnerState.Static); + } + } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs new file mode 100644 index 000000000..cbeb71ff8 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs @@ -0,0 +1,42 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable CompareOfFloatsByEqualityOperator + +using Unity.Mathematics; +using VisualPinball.Engine.Common; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class GateVelocityPhysics + { + internal static void UpdateVelocities(ref GateMovementData movementData, in GateStaticData data) + { + if (!movementData.IsOpen) { + if (math.abs(movementData.Angle) < data.AngleMin + 0.01f && math.abs(movementData.AngleSpeed) < 0.01f) { + // stop a bit earlier to prevent a nearly endless animation (especially for slow balls) + movementData.Angle = data.AngleMin; + movementData.AngleSpeed = 0.0f; + } + if (math.abs(movementData.AngleSpeed) != 0.0f && movementData.Angle != data.AngleMin) { + movementData.AngleSpeed -= math.sin(movementData.Angle) * data.GravityFactor * (float)(PhysicsConstants.PhysFactor / 100.0); // Center of gravity towards bottom of object, makes it stop vertical + movementData.AngleSpeed *= data.Damping; + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs deleted file mode 100644 index 98660361c..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocitySystem.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable CompareOfFloatsByEqualityOperator - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using VisualPinball.Engine.Common; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal partial class GateVelocitySystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("GateVelocitySystem"); - - protected override void OnUpdate() - { - var marker = PerfMarker; - Entities - .WithName("GateVelocityJob") - .ForEach((ref GateMovementData movementData, in GateStaticData data) => { - - marker.Begin(); - - if (!movementData.IsOpen) { - if (math.abs(movementData.Angle) < data.AngleMin + 0.01f && math.abs(movementData.AngleSpeed) < 0.01f) { - // stop a bit earlier to prevent a nearly endless animation (especially for slow balls) - movementData.Angle = data.AngleMin; - movementData.AngleSpeed = 0.0f; - } - if (math.abs(movementData.AngleSpeed) != 0.0f && movementData.Angle != data.AngleMin) { - movementData.AngleSpeed -= math.sin(movementData.Angle) * data.GravityFactor * (float)(PhysicsConstants.PhysFactor / 100.0); // Center of gravity towards bottom of object, makes it stop vertical - movementData.AngleSpeed *= data.Damping; - } - } - - marker.End(); - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs similarity index 55% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs index 1d2e660c2..f4fffb6f2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs @@ -23,27 +23,13 @@ namespace VisualPinballUnity { - [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal partial class SpinnerVelocitySystem : SystemBaseStub + internal partial class SpinnerVelocityPhysics { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("SpinnerVelocitySystem"); - - protected override void OnUpdate() + internal static void UpdateVelocities(ref SpinnerMovementData movementData, in SpinnerStaticData data) { - var marker = PerfMarker; - Entities - .WithName("SpinnerVelocityJob") - .ForEach((ref SpinnerMovementData movementData, in SpinnerStaticData data) => { - - marker.Begin(); - - // Center of gravity towards bottom of object, makes it stop vertical - movementData.AngleSpeed -= math.sin(movementData.Angle) * (float)(0.0025 * PhysicsConstants.PhysFactor); - movementData.AngleSpeed *= data.Damping; - - marker.End(); - - }).Run(); + // Center of gravity towards bottom of object, makes it stop vertical + movementData.AngleSpeed -= math.sin(movementData.Angle) * (float)(0.0025 * PhysicsConstants.PhysFactor); + movementData.AngleSpeed *= data.Damping; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocitySystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs.meta From 727e31bc07a4159ed03fc50f7a70095667b4abe9 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 8 Oct 2023 23:22:42 +0200 Subject: [PATCH 074/159] jobs: Add trigger animation. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 9 ++ .../VPT/Trigger/TriggerAnimation.cs | 82 ++++++++++++++ ...ystem.cs.meta => TriggerAnimation.cs.meta} | 0 .../VPT/Trigger/TriggerAnimationSystem.cs | 101 ------------------ .../VPT/Trigger/TriggerMovementSystem.cs | 64 ----------- .../VPT/Trigger/TriggerTransform.cs | 37 +++++++ ...ystem.cs.meta => TriggerTransform.cs.meta} | 0 7 files changed, 128 insertions(+), 165 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimation.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/{TriggerAnimationSystem.cs.meta => TriggerAnimation.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/{TriggerMovementSystem.cs.meta => TriggerTransform.cs.meta} (100%) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 5c1eb3bf7..b07e9bd93 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -235,6 +235,15 @@ private void Update() } } + // triggers + using (var enumerator = _triggerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var triggerState = ref enumerator.Current.Value; + var triggerTransform = _transforms[triggerState.AnimatedItemId]; + TriggerTransform.Update(triggerState.AnimatedItemId, in triggerState.Movement, triggerTransform); + } + } + #endregion } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimation.cs new file mode 100644 index 000000000..6219a8ec6 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimation.cs @@ -0,0 +1,82 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.VPT; + +namespace VisualPinball.Unity +{ + internal static class TriggerAnimation + { + internal static void Update(ref TriggerAnimationData data, ref TriggerMovementData movementData, in TriggerStaticData staticData, + float dTimeMs) + { + var oldTimeMsec = data.TimeMsec < dTimeMs ? data.TimeMsec : dTimeMs; + data.TimeMsec = dTimeMs; + var diffTimeMsec = dTimeMs - oldTimeMsec; + + var animLimit = staticData.Shape == TriggerShape.TriggerStar ? staticData.Radius * (float)(1.0 / 5.0) : 32.0f; + if (staticData.Shape == TriggerShape.TriggerButton) { + animLimit = staticData.Radius * (float)(1.0 / 10.0); + } + if (staticData.Shape == TriggerShape.TriggerWireC) { + animLimit = 60.0f; + } + if (staticData.Shape == TriggerShape.TriggerWireD) { + animLimit = 25.0f; + } + + var limit = animLimit * staticData.TableScaleZ; + + if (data.HitEvent) { + data.DoAnimation = true; + data.HitEvent = false; + // unhitEvent = false; // Bugfix: If HitEvent and unhitEvent happen at the same time, you want to favor the unhit, otherwise the switch gets stuck down. + movementData.HeightOffset = 0.0f; + data.MoveDown = true; + } + if (data.UnHitEvent) { + data.DoAnimation = true; + data.UnHitEvent = false; + data.HitEvent = false; + movementData.HeightOffset = limit; + data.MoveDown = false; + } + + if (data.DoAnimation) { + var step = diffTimeMsec * staticData.AnimSpeed * staticData.TableScaleZ; + if (data.MoveDown) { + step = -step; + } + movementData.HeightOffset += step; + + if (data.MoveDown) { + if (movementData.HeightOffset <= -limit) { + movementData.HeightOffset = -limit; + data.DoAnimation = false; + data.MoveDown = false; + } + + } else { + if (movementData.HeightOffset >= 0.0f) { + movementData.HeightOffset = 0.0f; + data.DoAnimation = false; + data.MoveDown = true; + } + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimation.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimation.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs deleted file mode 100644 index 04db3171c..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationSystem.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Profiling; -using VisualPinball.Engine.VPT; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class TriggerAnimationSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("TriggerAnimationSystem"); - - protected override void OnUpdate() - { - var dTime = SystemAPI.Time.DeltaTime * 1000; - var marker = PerfMarker; - - Entities - .WithName("TriggerAnimationJob") - .ForEach((ref TriggerAnimationData data, ref TriggerMovementData movementData, in TriggerStaticData staticData) => { - - marker.Begin(); - - var oldTimeMsec = data.TimeMsec < dTime ? data.TimeMsec : dTime; - data.TimeMsec = dTime; - var diffTimeMsec = dTime - oldTimeMsec; - - var animLimit = staticData.Shape == TriggerShape.TriggerStar ? staticData.Radius * (float)(1.0 / 5.0) : 32.0f; - if (staticData.Shape == TriggerShape.TriggerButton) { - animLimit = staticData.Radius * (float)(1.0 / 10.0); - } - if (staticData.Shape == TriggerShape.TriggerWireC) { - animLimit = 60.0f; - } - if (staticData.Shape == TriggerShape.TriggerWireD) { - animLimit = 25.0f; - } - - var limit = animLimit * staticData.TableScaleZ; - - if (data.HitEvent) { - data.DoAnimation = true; - data.HitEvent = false; - // unhitEvent = false; // Bugfix: If HitEvent and unhitEvent happen at the same time, you want to favor the unhit, otherwise the switch gets stuck down. - movementData.HeightOffset = 0.0f; - data.MoveDown = true; - } - if (data.UnHitEvent) { - data.DoAnimation = true; - data.UnHitEvent = false; - data.HitEvent = false; - movementData.HeightOffset = limit; - data.MoveDown = false; - } - - if (data.DoAnimation) { - var step = diffTimeMsec * staticData.AnimSpeed * staticData.TableScaleZ; - if (data.MoveDown) { - step = -step; - } - movementData.HeightOffset += step; - - if (data.MoveDown) { - if (movementData.HeightOffset <= -limit) { - movementData.HeightOffset = -limit; - data.DoAnimation = false; - data.MoveDown = false; - } - - } else { - if (movementData.HeightOffset >= 0.0f) { - movementData.HeightOffset = 0.0f; - data.DoAnimation = false; - data.MoveDown = true; - } - } - } - - marker.End(); - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs deleted file mode 100644 index 90d3cc008..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System.Collections.Generic; -using Unity.Entities; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -using Physics = UnityEngine.Physics; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class TriggerMovementSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("TriggerMovementSystem"); - - private Player _player; - private readonly Dictionary _initialOffset = new(); - - protected override void OnStartRunning() - { - base.OnStartRunning(); - _player = Object.FindObjectOfType(); - } - - protected override void OnUpdate() - { - var marker = PerfMarker; - - // fixme job - // Entities.WithoutBurst().WithName("TriggerMovementJob").ForEach((Entity entity, in TriggerMovementData data) => { - // - // marker.Begin(); - // - // var transform = _player.TriggerTransforms[entity]; - // if (!_initialOffset.ContainsKey(entity)) { - // _initialOffset[entity] = transform.position.y; - // } - // - // var worldPos = transform.position; - // worldPos.y = _initialOffset[entity] + VisualPinball.Unity.Physics.ScaleToWorld(data.HeightOffset); - // transform.position = worldPos; - // - // marker.End(); - // - // }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs new file mode 100644 index 000000000..427769c4d --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs @@ -0,0 +1,37 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Generic; +using UnityEngine; +using VisualPinball.Unity; +using Physics = VisualPinball.Unity.Physics; + +namespace VisualPinballUnity +{ + internal static class TriggerTransform + { + private static readonly Dictionary _initialOffset = new(); + + internal static void Update(int itemId, in TriggerMovementData data, Transform transform) + { + var worldPos = transform.position; + _initialOffset.TryAdd(itemId, worldPos.y); + + worldPos.y = _initialOffset[itemId] + Physics.ScaleToWorld(data.HeightOffset); + transform.position = worldPos; + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs.meta From 13c6c0b7b6175c28ab41b4a1fd10daaeb35dda52 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 8 Oct 2023 23:23:12 +0200 Subject: [PATCH 075/159] jobs: Fix InsideOfs and dequeue events. --- .../VisualPinball.Unity/Game/InsideOfs.cs | 11 ++- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 37 +++++--- .../VisualPinball.Unity/Game/Player.cs | 88 ++++++++++--------- .../Physics/Event/EventData.cs | 2 + 4 files changed, 80 insertions(+), 58 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs index e9a769968..9ec27e078 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/InsideOfs.cs @@ -1,5 +1,6 @@ using System; using Unity.Collections; +using VisualPinball.Unity.Collections; namespace VisualPinball.Unity { @@ -19,8 +20,9 @@ internal void SetInsideOf(int itemId, int ballId) if (!_insideOfs.ContainsKey(itemId)) { _insideOfs.Add(itemId, new BitField64()); } - - _insideOfs[itemId].SetBits(GetBitIndex(ballId), true); + + ref var bits = ref _insideOfs.GetValueByRef(itemId); + bits.SetBits(GetBitIndex(ballId), true); } internal void SetOutsideOf(int itemId, int ballId) @@ -28,8 +30,9 @@ internal void SetOutsideOf(int itemId, int ballId) if (!_insideOfs.ContainsKey(itemId)) { return; } - - _insideOfs[itemId].SetBits(GetBitIndex(ballId), false); + + ref var bits = ref _insideOfs.GetValueByRef(itemId); + bits.SetBits(GetBitIndex(ballId), false); ClearBitIndex(ballId); ClearItems(itemId); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index b07e9bd93..c7db6384b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -1,5 +1,4 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team +// Copyright (C) 2023 freezy and VPE Team // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -25,7 +24,6 @@ using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Common; -using VisualPinball.Unity.Collections; using VisualPinballUnity; using Debug = UnityEngine.Debug; @@ -57,6 +55,8 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private readonly Queue _inputActions = new(); + [NonSerialized] private Player _player; + private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); internal void Register(T item) where T : MonoBehaviour @@ -84,10 +84,13 @@ internal void Schedule(InputAction action) _inputActions.Enqueue(action); } + private void Awake() + { + _player = GetComponent(); + } + private void Start() { - var player = GetComponent(); - // init state var env = new PhysicsEnv(NowUsec, GetComponent()); _insideOfs = new InsideOfs(Allocator.Persistent); @@ -98,7 +101,7 @@ private void Start() Debug.Log($"Found {colliderItems.Length} collidable items."); var colliders = new ColliderReference(Allocator.TempJob); foreach (var colliderItem in colliderItems) { - colliderItem.GetColliders(player, ref colliders, 0); + colliderItem.GetColliders(_player, ref colliders, 0); } // allocate colliders @@ -146,7 +149,7 @@ private void Update() var events = _eventQueue.AsParallelWriter(); var updatePhysics = new UpdatePhysicsJob { InitialTimeUsec = NowUsec, - DeltaTime = Time.deltaTime * 1000, + DeltaTimeMs = Time.deltaTime * 1000, PhysicsEnv = _physicsEnv, Octree = _octree, Colliders = _colliders, @@ -180,6 +183,11 @@ private void Update() // run physics loop updatePhysics.Run(); + // dequeue events + while (_eventQueue.TryDequeue(out var eventData)) { + _player.OnEvent(in eventData); + } + // retrieve updated data _balls = updatePhysics.Balls; _physicsEnv = updatePhysics.PhysicsEnv; @@ -278,8 +286,7 @@ internal struct UpdatePhysicsJob : IJob [ReadOnly] public ulong InitialTimeUsec; - [ReadOnly] - public float DeltaTime; + public float DeltaTimeMs; public NativeArray PhysicsEnv; public NativeOctree Octree; @@ -355,14 +362,22 @@ public void Execute() while (enumerator.MoveNext()) { ref var bumperState = ref enumerator.Current.Value; if (bumperState.RingItemId != 0) { - BumperRingAnimation.Update(ref bumperState.RingAnimation, DeltaTime); + BumperRingAnimation.Update(ref bumperState.RingAnimation, DeltaTimeMs); } if (bumperState.SkirtItemId != 0) { - BumperSkirtAnimation.Update(ref bumperState.SkirtAnimation, DeltaTime); + BumperSkirtAnimation.Update(ref bumperState.SkirtAnimation, DeltaTimeMs); } } } + // trigger + using (var enumerator = TriggerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var triggerState = ref enumerator.Current.Value; + TriggerAnimation.Update(ref triggerState.Animation, ref triggerState.Movement, in triggerState.Static, DeltaTimeMs); + } + } + #endregion env.CurPhysicsFrameTime = env.NextPhysicsFrameTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index d113498be..670660540 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -454,49 +454,51 @@ private void RegisterCollider(int itemId, IApiColliderGenerator apiColl) public void OnEvent(in EventData eventData) { - switch (eventData.eventId) { - case EventId.HitEventsHit: - if (!_hittables.ContainsKey(eventData.ItemId)) { - Debug.LogError($"Cannot find entity {eventData.ItemId} in hittables."); - } - _hittables[eventData.ItemId].OnHit(eventData.BallId); - break; - - case EventId.HitEventsUnhit: - _hittables[eventData.ItemId].OnHit(eventData.BallId, true); - break; - - case EventId.LimitEventsBos: - _rotatables[eventData.ItemId].OnRotate(eventData.FloatParam, false); - break; - - case EventId.LimitEventsEos: - _rotatables[eventData.ItemId].OnRotate(eventData.FloatParam, true); - break; - - case EventId.SpinnerEventsSpin: - _spinnables[eventData.ItemId].OnSpin(); - break; - - case EventId.FlipperEventsCollide: - _collidables[eventData.ItemId].OnCollide(eventData.BallId, eventData.FloatParam); - break; - - case EventId.SurfaceEventsSlingshot: - _slingshots[eventData.ItemId].OnSlingshot(eventData.BallId); - break; - - case EventId.TargetEventsDropped: - _droppables[eventData.ItemId].OnDropStatusChanged(true, eventData.BallId); - break; - - case EventId.TargetEventsRaised: - _droppables[eventData.ItemId].OnDropStatusChanged(false, eventData.BallId); - break; - - default: - throw new InvalidOperationException($"Unknown event {eventData.eventId} for entity {eventData.ItemId}"); - } + Debug.Log(eventData); + // todo re-enable + // switch (eventData.eventId) { + // case EventId.HitEventsHit: + // if (!_hittables.ContainsKey(eventData.ItemId)) { + // Debug.LogError($"Cannot find item {eventData.ItemId} in hittables."); + // } + // _hittables[eventData.ItemId].OnHit(eventData.BallId); + // break; + // + // case EventId.HitEventsUnhit: + // _hittables[eventData.ItemId].OnHit(eventData.BallId, true); + // break; + // + // case EventId.LimitEventsBos: + // _rotatables[eventData.ItemId].OnRotate(eventData.FloatParam, false); + // break; + // + // case EventId.LimitEventsEos: + // _rotatables[eventData.ItemId].OnRotate(eventData.FloatParam, true); + // break; + // + // case EventId.SpinnerEventsSpin: + // _spinnables[eventData.ItemId].OnSpin(); + // break; + // + // case EventId.FlipperEventsCollide: + // _collidables[eventData.ItemId].OnCollide(eventData.BallId, eventData.FloatParam); + // break; + // + // case EventId.SurfaceEventsSlingshot: + // _slingshots[eventData.ItemId].OnSlingshot(eventData.BallId); + // break; + // + // case EventId.TargetEventsDropped: + // _droppables[eventData.ItemId].OnDropStatusChanged(true, eventData.BallId); + // break; + // + // case EventId.TargetEventsRaised: + // _droppables[eventData.ItemId].OnDropStatusChanged(false, eventData.BallId); + // break; + // + // default: + // throw new InvalidOperationException($"Unknown event {eventData.eventId} for entity {eventData.ItemId}"); + // } } internal void BallCreated(Entity ballEntity, GameObject ball) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs index 79cf5e8c8..d9400e282 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs @@ -65,5 +65,7 @@ public EventData(EventId eventId, int itemId, float floatParam, bool groupEvent FloatParam = floatParam; GroupEvent = groupEvent; } + + public override string ToString() => $"Event {eventId} for item {ItemId} by ball {BallId} ({FloatParam})"; } } From d4ce108d39b57f2308355e2f3fc705eceae0bc53 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 9 Oct 2023 21:09:04 +0200 Subject: [PATCH 076/159] jobs: Migrate plunger code. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 8 + .../VisualPinball.Unity/Game/PhysicsEngine.cs | 31 +- .../VisualPinball.Unity/Game/Player.cs | 4 - .../VPT/Plunger/PlungerAnimation.cs | 33 ++ ...ystem.cs.meta => PlungerAnimation.cs.meta} | 0 .../VPT/Plunger/PlungerAnimationSystem.cs | 51 --- .../VPT/Plunger/PlungerDisplacementPhysics.cs | 119 ++++++ ...eta => PlungerDisplacementPhysics.cs.meta} | 0 .../VPT/Plunger/PlungerDisplacementSystem.cs | 157 -------- .../Plunger/PlungerTransformationSystem.cs | 55 --- .../PlungerTransformationSystem.cs.meta | 11 - .../VPT/Plunger/PlungerVelocityPhysics.cs | 329 +++++++++++++++++ ...cs.meta => PlungerVelocityPhysics.cs.meta} | 0 .../VPT/Plunger/PlungerVelocitySystem.cs | 343 ------------------ 14 files changed, 519 insertions(+), 622 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerAnimationSystem.cs.meta => PlungerAnimation.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerDisplacementSystem.cs.meta => PlungerDisplacementPhysics.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerVelocitySystem.cs.meta => PlungerVelocityPhysics.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 52fade3d0..a3f80724f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -109,6 +109,14 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) hitTime, ref state.EventQueue); } } + // plunger + using (var enumerator = state.PlungerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var plungerState = ref enumerator.Current.Value; + PlungerDisplacementPhysics.UpdateDisplacement(plungerState.ItemId, ref plungerState.Movement, ref plungerState.Collider, + in plungerState.Static, hitTime, ref state.EventQueue); + } + } // spinners using (var enumerator = state.SpinnerStates.GetEnumerator()) { while (enumerator.MoveNext()) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index c7db6384b..cc0cbc9ea 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -52,6 +52,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private readonly Dictionary _ballLookup = new(); [NonSerialized] private readonly Dictionary _transforms = new(); + [NonSerialized] private readonly Dictionary _skinnedMeshRenderers = new(); [NonSerialized] private readonly Queue _inputActions = new(); @@ -72,7 +73,10 @@ internal void Register(T item) where T : MonoBehaviour case DropTargetComponent c: _dropTargetStates[itemId] = c.CreateState(); break; case HitTargetComponent c: _hitTargetStates[itemId] = c.CreateState(); break; case KickerComponent c: _kickerStates[itemId] = c.CreateState(); break; - case PlungerComponent c: _plungerStates[itemId] = c.CreateState(); break; + case PlungerComponent c: + _plungerStates[itemId] = c.CreateState(); + _skinnedMeshRenderers[itemId] = c.GetComponentsInChildren(); + break; case SpinnerComponent c: _spinnerStates[itemId] = c.CreateState(); break; case SurfaceComponent c: _surfaceStates[itemId] = c.CreateState(); break; case TriggerComponent c: _triggerStates[itemId] = c.CreateState(); break; @@ -234,6 +238,16 @@ private void Update() } } + // plungers + using (var enumerator = _plungerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var plungerState = ref enumerator.Current.Value; + foreach (var skinnedMeshRenderer in _skinnedMeshRenderers[enumerator.Current.Key]) { + skinnedMeshRenderer.SetBlendShapeWeight(0, plungerState.Animation.Position); + } + } + } + // spinners using (var enumerator = _spinnerStates.GetEnumerator()) { while (enumerator.MoveNext()) { @@ -342,6 +356,13 @@ public void Execute() GateVelocityPhysics.UpdateVelocities(ref gateState.Movement, in gateState.Static); } } + // plungers + using (var enumerator = PlungerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var plungerState = ref enumerator.Current.Value; + PlungerVelocityPhysics.UpdateVelocities(ref plungerState.Movement, ref plungerState.Velocity, in plungerState.Static); + } + } // spinners using (var enumerator = SpinnerStates.GetEnumerator()) { while (enumerator.MoveNext()) { @@ -370,6 +391,14 @@ public void Execute() } } + // plunger + using (var enumerator = PlungerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var plungerState = ref enumerator.Current.Value; + PlungerAnimation.Update(ref plungerState.Animation, in plungerState.Movement, in plungerState.Static); + } + } + // trigger using (var enumerator = TriggerStates.GetEnumerator()) { while (enumerator.MoveNext()) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 670660540..8ffd3beee 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -23,7 +23,6 @@ using UnityEngine; using UnityEngine.InputSystem; using VisualPinball.Engine.Common; -using VisualPinball.Engine.Game; using VisualPinball.Engine.Game.Engines; using VisualPinball.Engine.VPT.Trigger; using VisualPinballUnity; @@ -81,7 +80,6 @@ public class Player : MonoBehaviour internal readonly Dictionary DropTargetTransforms = new Dictionary(); internal readonly Dictionary SpinnerPlateTransforms = new Dictionary(); internal readonly Dictionary TriggerTransforms = new Dictionary(); - internal readonly Dictionary PlungerSkinnedMeshRenderers = new Dictionary(); internal readonly Dictionary Balls = new Dictionary(); internal IEnumerable ColliderGenerators => _colliderGenerators; @@ -306,8 +304,6 @@ public void RegisterPlunger(PlungerComponent component, InputActionReference act actionRef.action.performed += plungerApi.OnAnalogPlunge; _actions.Add((actionRef.action, plungerApi.OnAnalogPlunge)); } - - PlungerSkinnedMeshRenderers[component.GetInstanceID()] = component.gameObject.GetComponentsInChildren(); } public void RegisterPlayfield(GameObject go) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs new file mode 100644 index 000000000..995d66234 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs @@ -0,0 +1,33 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Mathematics; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class PlungerAnimation + { + internal static void Update(ref PlungerAnimationData animationData, in PlungerMovementData movementData, + in PlungerStaticData staticData) + { + var frame0 = (int)((movementData.Position - staticData.FrameStart) / (staticData.FrameEnd - staticData.FrameStart) * (staticData.NumFrames - 1) + 0.5f); + var frame = frame0 < 0 ? 0 : frame0 >= staticData.NumFrames ? staticData.NumFrames - 1 : frame0; + + animationData.Position = math.clamp((float)frame / staticData.NumFrames, 0, 1); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs deleted file mode 100644 index 716505140..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationSystem.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class PlungerAnimationSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("PlungerAnimationSystem"); - - protected override void OnUpdate() - { - var marker = PerfMarker; - - Entities.WithName("PlungerAnimationJob") - .ForEach((ref PlungerAnimationData animationData, in PlungerMovementData movementData, in PlungerStaticData staticData) => - { - marker.Begin(); - - var frame0 = (int)((movementData.Position - staticData.FrameStart) / (staticData.FrameEnd - staticData.FrameStart) * (staticData.NumFrames - 1) + 0.5f); - var frame = frame0 < 0 ? 0 : frame0 >= staticData.NumFrames ? staticData.NumFrames - 1 : frame0; - - //Debug.Log($"[plunger] frame0 = {frame0} frame = {frame}"); - - animationData.Position = math.clamp((float)frame / staticData.NumFrames, 0, 1); - - marker.End(); - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs new file mode 100644 index 000000000..3bb08b5f4 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs @@ -0,0 +1,119 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Collections; +using Unity.Mathematics; +using VisualPinball.Engine.Game; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class PlungerDisplacementPhysics + { + internal static void UpdateDisplacement(int itemId, ref PlungerMovementData movementData, + ref PlungerColliderData colliderData, in PlungerStaticData staticData, float dTime, + ref NativeQueue.ParallelWriter events) + { + // figure the travel distance + var dx = dTime * movementData.Speed; + + // figure the position change + movementData.Position += dx; + + // apply the travel limit + if (movementData.Position < movementData.TravelLimit) { + movementData.Position = movementData.TravelLimit; + } + + // if we're in firing mode and we've crossed the bounce position, reverse course + var relPos = (movementData.Position - staticData.FrameEnd) / staticData.FrameLen; + var bouncePos = staticData.RestPosition + movementData.FireBounce; + if (movementData.FireTimer != 0 && dTime != 0.0f && + (movementData.FireSpeed < 0.0f ? relPos <= bouncePos : relPos >= bouncePos)) + { + // stop at the bounce position + movementData.Position = staticData.FrameEnd + bouncePos * staticData.FrameLen; + + // reverse course at reduced speed + movementData.FireSpeed = -movementData.FireSpeed * 0.4f; + + // figure the new bounce as a fraction of the previous bounce + movementData.FireBounce *= -0.4f; + } + + // apply the travel limit (again) + if (movementData.Position < movementData.TravelLimit) { + movementData.Position = movementData.TravelLimit; + } + + // limit motion to the valid range + if (dTime != 0.0f) { + + if (movementData.Position < staticData.FrameEnd) { + movementData.Speed = 0.0f; + movementData.Position = staticData.FrameEnd; + + } else if (movementData.Position > staticData.FrameStart) { + movementData.Speed = 0.0f; + movementData.Position = staticData.FrameStart; + } + + // apply the travel limit (yet again) + if (movementData.Position < movementData.TravelLimit) { + movementData.Position = movementData.TravelLimit; + } + } + + // the travel limit applies to one displacement update only - reset it + movementData.TravelLimit = staticData.FrameEnd; + + // fire an Start/End of Stroke events, as appropriate + var strokeEventLimit = staticData.FrameLen / 50.0f; + var strokeEventHysteresis = strokeEventLimit * 2.0f; + if (movementData.StrokeEventsArmed && movementData.Position + dx > staticData.FrameStart - strokeEventLimit) { + events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, math.abs(movementData.Speed))); + movementData.StrokeEventsArmed = false; + + } else if (movementData.StrokeEventsArmed && movementData.Position + dx < staticData.FrameEnd + strokeEventLimit) { + events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, math.abs(movementData.Speed))); + movementData.StrokeEventsArmed = false; + + } else if (movementData.Position > staticData.FrameEnd + strokeEventHysteresis && movementData.Position < staticData.FrameStart - strokeEventHysteresis) { + // away from the limits - arm the stroke events + movementData.StrokeEventsArmed = true; + } + + // update the display + UpdateCollider(movementData.Position, ref colliderData); + } + + private static void UpdateCollider(float len, ref PlungerColliderData colliderData) + { + colliderData.LineSegSide0.V1y = len; + colliderData.LineSegSide1.V2y = len; + + colliderData.LineSegEnd.V2y = len; + colliderData.LineSegEnd.V1y = len; // + 0.0001f; + + colliderData.JointEnd0.XyY = len; + colliderData.JointEnd1.XyY = len; // + 0.0001f; + + colliderData.LineSegSide0.CalcNormal(); + colliderData.LineSegSide1.CalcNormal(); + colliderData.LineSegEnd.CalcNormal(); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs deleted file mode 100644 index 7fdc1cce7..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementSystem.cs +++ /dev/null @@ -1,157 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Collections; -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Engine.Game; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal partial class PlungerDisplacementSystem : SystemBaseStub - { - private Player _player; - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - private NativeQueue _eventQueue; - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("PlungerDisplacementSystem"); - - protected override void OnCreate() - { - _player = Object.FindObjectOfType(); - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - _eventQueue = new NativeQueue(Allocator.Persistent); - } - - protected override void OnDestroy() - { - _eventQueue.Dispose(); - } - - protected override void OnUpdate() - { - var events = _eventQueue.AsParallelWriter(); - var dTime = _simulateCycleSystemGroup.HitTime; - var marker = PerfMarker; - - // fixme job - // Entities.WithName("PlungerDisplacementJob").ForEach((Entity entity, ref PlungerMovementData movementData, - // ref PlungerColliderData colliderData, in PlungerStaticData staticData) => - // { - // marker.Begin(); - // - // // figure the travel distance - // var dx = dTime * movementData.Speed; - // - // // figure the position change - // movementData.Position += dx; - // - // // apply the travel limit - // if (movementData.Position < movementData.TravelLimit) { - // movementData.Position = movementData.TravelLimit; - // } - // - // // if we're in firing mode and we've crossed the bounce position, reverse course - // var relPos = (movementData.Position - staticData.FrameEnd) / staticData.FrameLen; - // var bouncePos = staticData.RestPosition + movementData.FireBounce; - // if (movementData.FireTimer != 0 && dTime != 0.0f && - // (movementData.FireSpeed < 0.0f ? relPos <= bouncePos : relPos >= bouncePos)) - // { - // // stop at the bounce position - // movementData.Position = staticData.FrameEnd + bouncePos * staticData.FrameLen; - // - // // reverse course at reduced speed - // movementData.FireSpeed = -movementData.FireSpeed * 0.4f; - // - // // figure the new bounce as a fraction of the previous bounce - // movementData.FireBounce *= -0.4f; - // } - // - // // apply the travel limit (again) - // if (movementData.Position < movementData.TravelLimit) { - // movementData.Position = movementData.TravelLimit; - // } - // - // // limit motion to the valid range - // if (dTime != 0.0f) { - // - // if (movementData.Position < staticData.FrameEnd) { - // movementData.Speed = 0.0f; - // movementData.Position = staticData.FrameEnd; - // - // } else if (movementData.Position > staticData.FrameStart) { - // movementData.Speed = 0.0f; - // movementData.Position = staticData.FrameStart; - // } - // - // // apply the travel limit (yet again) - // if (movementData.Position < movementData.TravelLimit) { - // movementData.Position = movementData.TravelLimit; - // } - // } - // - // // the travel limit applies to one displacement update only - reset it - // movementData.TravelLimit = staticData.FrameEnd; - // - // // fire an Start/End of Stroke events, as appropriate - // var strokeEventLimit = staticData.FrameLen / 50.0f; - // var strokeEventHysteresis = strokeEventLimit * 2.0f; - // if (movementData.StrokeEventsArmed && movementData.Position + dx > staticData.FrameStart - strokeEventLimit) { - // events.Enqueue(new EventData(EventId.LimitEventsBos, entity, math.abs(movementData.Speed))); - // movementData.StrokeEventsArmed = false; - // - // } else if (movementData.StrokeEventsArmed && movementData.Position + dx < staticData.FrameEnd + strokeEventLimit) { - // events.Enqueue(new EventData(EventId.LimitEventsEos, entity, math.abs(movementData.Speed))); - // movementData.StrokeEventsArmed = false; - // - // } else if (movementData.Position > staticData.FrameEnd + strokeEventHysteresis && movementData.Position < staticData.FrameStart - strokeEventHysteresis) { - // // away from the limits - arm the stroke events - // movementData.StrokeEventsArmed = true; - // } - // - // // update the display - // UpdateCollider(movementData.Position, ref colliderData); - // - // marker.End(); - // }).Run(); - - // dequeue events - while (_eventQueue.TryDequeue(out var eventData)) { - _player.OnEvent(in eventData); - } - } - - private static void UpdateCollider(float len, ref PlungerColliderData colliderData) - { - colliderData.LineSegSide0.V1y = len; - colliderData.LineSegSide1.V2y = len; - - colliderData.LineSegEnd.V2y = len; - colliderData.LineSegEnd.V1y = len; // + 0.0001f; - - colliderData.JointEnd0.XyY = len; - colliderData.JointEnd1.XyY = len; // + 0.0001f; - - colliderData.LineSegSide0.CalcNormal(); - colliderData.LineSegSide1.CalcNormal(); - colliderData.LineSegEnd.CalcNormal(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs deleted file mode 100644 index bbfdf37a3..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class PlungerTransformationSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("PlungerTransformationSystem"); - - private Player _player; - - protected override void OnStartRunning() - { - base.OnStartRunning(); - _player = Object.FindObjectOfType(); - } - - protected override void OnUpdate() - { - var marker = PerfMarker; - - // fixme job - // Entities.WithoutBurst().WithName("PlungerTransformationJob").ForEach((Entity entity, in PlungerAnimationData animationData) => { - // - // marker.Begin(); - // - // foreach (var skinnedMeshRenderer in _player.PlungerSkinnedMeshRenderers[entity]) { - // skinnedMeshRenderer.SetBlendShapeWeight(0, animationData.Position); - // } - // marker.End(); - // - // }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs.meta deleted file mode 100644 index 035df24c5..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerTransformationSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e26bea61605afb04681956ccf866fee6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs new file mode 100644 index 000000000..fd4e7c2ba --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs @@ -0,0 +1,329 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.VPT.Plunger; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class PlungerVelocityPhysics + { + internal static void UpdateVelocities(ref PlungerMovementData movementData, ref PlungerVelocityData velocityData, + in PlungerStaticData staticData) + { + // figure our current position in relative coordinates (0.0-1.0, + // where 0.0 is the maximum forward position and 1.0 is the + // maximum retracted position) + var pos = (movementData.Position - staticData.FrameEnd) / staticData.FrameLen; + + var mech = staticData.IsMechPlunger ? movementData.AnalogPosition : 0.0f; + + // calculate the delta from the last reading + var dMech = velocityData.Mech0 - mech; + + // Frame-to-frame mech movement threshold for detecting a release + // motion. 1.0 is the full range of travel, which corresponds + // to about 3" on a standard pinball plunger. We want to choose + // the value here so that it's faster than the player is likely + // to move the plunger manually, but slower than the plunger + // typically moves under spring power when released. It appears + // from observation that a real plunger moves at something on the + // order of 3 m/s. Figure the fastest USB update interval will + // be 10ms, typical is probably 25ms, and slowest is maybe 40ms; + // and figure the bracket speed range down to about 1 m/s. This + // gives us a distance per USB interval of from 25mm to 100mm. + // 25mm translates to .32 of our distance units (0.0-1.0 scale). + // The lower we make this, the more sensitive we'll be at + // detecting releases, but if we make it too low we might mistake + // manual movements for releases. In practice, it seems safe to + // lower it to about 0.2 - this doesn't seem to cause false + // positives and seems reliable at identifying actual releases. + const float releaseThreshold = 0.2f; + + // note if we're acting as an auto plunger + var autoPlunger = staticData.IsAutoPlunger; + + // check which forces are acting on us + if (movementData.FireTimer > 0) { + // Fire mode. In this mode, we're moving freely under the spring + // forces at the speed we calculated when we initiated the release. + // Simply leave the speed unchanged. + // + // Decrement the release mode timer. The mode ends after the + // timeout elapses, even if the mech plunger hasn't actually + // come to rest. This ensures that we don't get stuck in this + // mode, and also allows us to sync up again with the real + // plunger after a respectable pause if the user is just + // moving it around a lot. + movementData.Speed = movementData.FireSpeed; + --movementData.FireTimer; + + } else if (velocityData.AutoFireTimer > 0) { + // The Auto Fire timer is running. We start this timer when we + // send a synthetic KeyDown(Return) event to the script to simulate + // a Launch Ball event when the user pulls back and releases the + // mechanical plunger and we're operating as an auto plunger. + // When the timer reaches zero, we'll send the corresponding + // KeyUp event and cancel the timer. + if (--velocityData.AutoFireTimer == 0) { + // todo event + // if (g_pplayer != 0) { + // g_pplayer->m_ptable->FireKeyEvent(DISPID_GameEvents_KeyUp, g_pplayer->m_rgKeys[ePlungerKey]); + // } + } + + } else if (autoPlunger && dMech > releaseThreshold) { + // Release motion detected in Auto Plunger mode. + // + // If we're acting as an auto plunger, and the player performs + // a pull-and-release motion on the mechanical plunger, simulate + // a Launch Ball event. + // + // An Auto Plunger simulates a solenoid-driven ball launcher + // on a table like Medieval Madness. On this type of game, + // the original machine doesn't have a spring-loaded plunger. + // for the user to operate manually. The user-operated control + // is instead a button of some kind (the physical form varies + // quite a bit, from big round pushbuttons to gun triggers to + // levers to rotating knobs, but they all amount to momentary + // on/off switches in different guises). But on virtual + // cabinets, the mechanical plunger doesn't just magically + // disappear when you load Medieval Madness! So the idea here + // is that we can use a mech plunger to simulate a button. + // It's pretty simple and natural: you just perform the normal + // action that you're accustomed to doing with a plunger, + // namely pulling it back and letting it go. The software + // observes this gesture, and rather than trying to simulate + // the motion directly on the software plunger, we simply + // turn it into a synthetic Launch Ball keyboard event. This + // amounts to sending a KeyDown(Return) message to the script, + // followed a short time later by a KeyUp(Return). The script + // will then act exactly like it would if the user had actually + // pressed the Return key (or, equivalently on a cabinet, the + // Launch Ball button). + + // Send a KeyDown(Return) to the table script. This + // will allow the script to set ROM switch levels or + // perform any other tasks it normally does when the + // actual Launch Ball button is pressed. + + // todo event + // if (g_pplayer != 0) { + // g_pplayer->m_ptable->FireKeyEvent(DISPID_GameEvents_KeyDown, g_pplayer->m_rgKeys[ePlungerKey]); + // } + + // start the timer to send the corresponding KeyUp in 100ms + velocityData.AutoFireTimer = 101; + + } else if (velocityData.PullForce != 0.0f) { + // A "pull" force is in effect. This is a *simulated* pull, so + // it overrides the real physical plunger position. + // + // Simply update the model speed by applying the acceleration + // due to the pull force. + // + // Force = mass*acceleration -> a = F/m. Increase the speed + // by the acceleration. Technically we're calculating dv = a dt, + // but we can elide the elapsed time factor because it's + // effectively a constant that's implicitly folded into the + // pull force value. + movementData.Speed += velocityData.PullForce / Plunger.PlungerMass; + + if (!velocityData.AddRetractMotion) { + // this is the normal PullBack branch + + // if we're already at the maximum retracted position, stop + if (movementData.Position > staticData.FrameStart) { + movementData.Speed = 0.0f; + movementData.Position = staticData.FrameStart; + } + + // if we're already at the minimum retracted position, stop + if (movementData.Position < staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen) { + movementData.Speed = 0.0f; + movementData.Position = staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen; + } + + } else { + // this is the PullBackandRetract branch + + // after reaching the max. position the plunger should retract until it reaches the min. position and then start again + // if we're already at the maximum retracted position, reverse + if (movementData.Position >= staticData.FrameStart && velocityData.PullForce > 0) { + movementData.Speed = 0.0f; + movementData.Position = staticData.FrameStart; + velocityData.RetractWaitLoop++; + if (velocityData.RetractWaitLoop > 1000) { // 1 sec, related to PHYSICS_STEPTIME + velocityData.PullForce = -velocityData.InitialSpeed; + movementData.Position = staticData.FrameStart; + movementData.RetractMotion = true; + velocityData.RetractWaitLoop = 0; + } + } + + // if we're already at the minimum retracted position, start again + if (movementData.Position <= staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen && velocityData.PullForce <= 0) { + movementData.Speed = 0.0f; + velocityData.PullForce = velocityData.InitialSpeed; + movementData.Position = staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen; + } + + // reset retract motion indicator only after the rest position has been left, to avoid ball interactions + // use a linear pullback motion + if (movementData.Position > 1.0f + staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen && velocityData.PullForce > 0) { + movementData.RetractMotion = false; + movementData.Speed = 3.0f * velocityData.PullForce; // 3 = magic + } + } + + } else if (dMech > releaseThreshold) { + // Normal mode, fast forward motion detected. Consider this + // to be a release event. + // + // The release motion of a physical plunger is much faster + // than our sampling rate can keep up with, so we can't just + // use the joystick readings directly. The problem is that a + // real plunger can shoot all the way forward, bounce all the + // way back, and shoot forward again in the time between two + // consecutive samples. A real plunger moves at around 3-5m/s, + // which translates to 3-5mm/ms, or 30-50mm per 10ms sampling + // period. The whole plunger travel distance is ~65mm. + // So in one reading, we can travel almost the whole range! + // This means that samples are effectively random during a + // release motion. We might happen to get lucky and have + // our sample timing align perfectly with a release, so that + // we get one reading at the retracted position just before + // a release and the very next reading at the full forward + // position. Or we might get unlikely and catch one reading + // halfway down the initial initial lunge and the next reading + // at the very apex of the bounce back - and if we took those + // two readings at face value, we'd be fooled into thinking + // the plunger was stationary at the halfway point! + // + // But there's hope. A real plunger's barrel spring is pretty + // inelastic, so the rebounds after a release damp out quickly. + // Observationally, each bounce bounces back to less than half + // of the previous one. So even with the worst-case aliasing, + // we can be confident that we'll see a declining trend in the + // samples during a release-bounce-bounce-bounce sequence. + // + // Our detection strategy is simply to consider any rapid + // forward motion to be a release. If we see the plunger move + // forward by more than the threshold distance, we'll consider + // it a release. See the comments above for how we chose the + // threshold value. + + // Go back through the recent history to find the apex of the + // release. Our "threshold" calculation is basically attempting + // to measure the instantaneous speed of the plunger as the + // difference in position divided by the time interval. But + // the time interval is extremely imprecise, because joystick + // reports aren't synchronized to our clock. In practice the + // time between USB reports is in the 10-30ms range, which gives + // us a considerable range of error in calculating an instantaneous + // speed. + // + // So instead of relying on the instantaneous speed alone, now + // that we're pretty sure a release motion is under way, go back + // through our recent history to find out where it really + // started. Scan the history for monotonically ascending values, + // and take the highest one we find. That's probably where the + // user actually released the plunger. + var apex = velocityData.Mech0; + if (velocityData.Mech1 > apex) { + apex = velocityData.Mech1; + if (velocityData.Mech2 > apex) { + apex = velocityData.Mech2; + } + } + + // trigger a release from the apex position + PlungerCommands.Fire(apex, ref velocityData, ref movementData, in staticData); + + } else { + // Normal mode, and NOT firing the plunger. In this mode, we + // simply want to make the on-screen plunger sync up with the + // position of the physical plunger. + // + // This isn't as simple as just setting the software plunger's + // position to magically match that of the physical plunger. If + // we did that, we'd break the simulation by making the software + // plunger move at infinite speed. This wouldn't rip the fabric + // of space-time or anything that dire, but it *would* prevent + // the collision detection code from working properly. + // + // So instead, sync up the positions by setting the software + // plunger in motion on a course for syncing up with the + // physical plunger, as fast as we can while maintaining a + // realistic speed in the simulation. + + // for a normal plunger, sync to the mech plunger; otherwise + // just go to the rest position + var target = autoPlunger ? staticData.RestPosition : mech; + + // figure the current difference in positions + var error = target - pos; + + // Model the software plunger as though it were connected to the + // mechanical plunger by a spring with spring constant 'mech + // strength'. The force from a stretched spring is -kx (spring + // constant times displacement); in this case, the displacement + // is the distance between the physical and virtual plunger tip + // positions ('error'). The force from an acceleration is ma, + // so the acceleration from the spring force is -kx/m. Apply + // this acceleration to the current plunger speed. While we're + // at it, apply some damping to the current speed to simulate + // friction. + // + // The 'normalize' factor is the table's normalization constant + // divided by 1300, for historical reasons. Old versions applied + // a 1/13 adjustment factor, which appears to have been empirically + // chosen to get the speed in the right range. The m_plungerNormalize + // factor has default value 100 in this version, so we need to + // divide it by 100 to get a multipler value. + // + // The 'dt' factor represents the amount of time that we're applying + // this acceleration. This is in "VP 9 physics frame" units, where + // 1.0 equals the amount of real time in one VP 9 physics frame. + // The other normalization factors were originally chosen for VP 9 + // timing, so we need to adjust for the new VP 10 time base. VP 10 + // runs physics frames at roughly 10x the rate of VP 9, so the time + // per frame is about 1/10 the VP 9 time. + const float plungerFriction = 0.95f; + const float normalize = Plunger.PlungerNormalize / 13.0f / 100.0f; + const float dt = 0.1f; + movementData.Speed *= plungerFriction; + movementData.Speed += error * staticData.FrameLen * velocityData.MechStrength / Plunger.PlungerMass * normalize * dt; + + // add any reverse impulse to the result + movementData.Speed += movementData.ReverseImpulse; + } + + // cancel any reverse impulse + movementData.ReverseImpulse = 0.0f; + + // Shift the current mech reading into the history list, if it's + // different from the last reading. Only keep distinct readings; + // the physics loop tends to run faster than the USB reporting + // rate, so we might see the same USB report several times here. + if (mech != velocityData.Mech0) { + velocityData.Mech2 = velocityData.Mech1; + velocityData.Mech1 = velocityData.Mech0; + velocityData.Mech0 = mech; + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs deleted file mode 100644 index c561c4991..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocitySystem.cs +++ /dev/null @@ -1,343 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Profiling; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal partial class PlungerVelocitySystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("PlungerVelocitySystem"); - - protected override void OnUpdate() - { - var marker = PerfMarker; - Entities.ForEach((ref PlungerMovementData movementData, ref PlungerVelocityData velocityData, - in PlungerStaticData staticData) => - { - marker.Begin(); - - // figure our current position in relative coordinates (0.0-1.0, - // where 0.0 is the maximum forward position and 1.0 is the - // maximum retracted position) - var pos = (movementData.Position - staticData.FrameEnd) / staticData.FrameLen; - - var mech = staticData.IsMechPlunger ? movementData.AnalogPosition : 0.0f; - - // calculate the delta from the last reading - var dMech = velocityData.Mech0 - mech; - - // Frame-to-frame mech movement threshold for detecting a release - // motion. 1.0 is the full range of travel, which corresponds - // to about 3" on a standard pinball plunger. We want to choose - // the value here so that it's faster than the player is likely - // to move the plunger manually, but slower than the plunger - // typically moves under spring power when released. It appears - // from observation that a real plunger moves at something on the - // order of 3 m/s. Figure the fastest USB update interval will - // be 10ms, typical is probably 25ms, and slowest is maybe 40ms; - // and figure the bracket speed range down to about 1 m/s. This - // gives us a distance per USB interval of from 25mm to 100mm. - // 25mm translates to .32 of our distance units (0.0-1.0 scale). - // The lower we make this, the more sensitive we'll be at - // detecting releases, but if we make it too low we might mistake - // manual movements for releases. In practice, it seems safe to - // lower it to about 0.2 - this doesn't seem to cause false - // positives and seems reliable at identifying actual releases. - const float releaseThreshold = 0.2f; - - // note if we're acting as an auto plunger - var autoPlunger = staticData.IsAutoPlunger; - - // check which forces are acting on us - if (movementData.FireTimer > 0) { - // Fire mode. In this mode, we're moving freely under the spring - // forces at the speed we calculated when we initiated the release. - // Simply leave the speed unchanged. - // - // Decrement the release mode timer. The mode ends after the - // timeout elapses, even if the mech plunger hasn't actually - // come to rest. This ensures that we don't get stuck in this - // mode, and also allows us to sync up again with the real - // plunger after a respectable pause if the user is just - // moving it around a lot. - movementData.Speed = movementData.FireSpeed; - --movementData.FireTimer; - - } else if (velocityData.AutoFireTimer > 0) { - // The Auto Fire timer is running. We start this timer when we - // send a synthetic KeyDown(Return) event to the script to simulate - // a Launch Ball event when the user pulls back and releases the - // mechanical plunger and we're operating as an auto plunger. - // When the timer reaches zero, we'll send the corresponding - // KeyUp event and cancel the timer. - if (--velocityData.AutoFireTimer == 0) { - // todo event - // if (g_pplayer != 0) { - // g_pplayer->m_ptable->FireKeyEvent(DISPID_GameEvents_KeyUp, g_pplayer->m_rgKeys[ePlungerKey]); - // } - } - - } else if (autoPlunger && dMech > releaseThreshold) { - // Release motion detected in Auto Plunger mode. - // - // If we're acting as an auto plunger, and the player performs - // a pull-and-release motion on the mechanical plunger, simulate - // a Launch Ball event. - // - // An Auto Plunger simulates a solenoid-driven ball launcher - // on a table like Medieval Madness. On this type of game, - // the original machine doesn't have a spring-loaded plunger. - // for the user to operate manually. The user-operated control - // is instead a button of some kind (the physical form varies - // quite a bit, from big round pushbuttons to gun triggers to - // levers to rotating knobs, but they all amount to momentary - // on/off switches in different guises). But on virtual - // cabinets, the mechanical plunger doesn't just magically - // disappear when you load Medieval Madness! So the idea here - // is that we can use a mech plunger to simulate a button. - // It's pretty simple and natural: you just perform the normal - // action that you're accustomed to doing with a plunger, - // namely pulling it back and letting it go. The software - // observes this gesture, and rather than trying to simulate - // the motion directly on the software plunger, we simply - // turn it into a synthetic Launch Ball keyboard event. This - // amounts to sending a KeyDown(Return) message to the script, - // followed a short time later by a KeyUp(Return). The script - // will then act exactly like it would if the user had actually - // pressed the Return key (or, equivalently on a cabinet, the - // Launch Ball button). - - // Send a KeyDown(Return) to the table script. This - // will allow the script to set ROM switch levels or - // perform any other tasks it normally does when the - // actual Launch Ball button is pressed. - - // todo event - // if (g_pplayer != 0) { - // g_pplayer->m_ptable->FireKeyEvent(DISPID_GameEvents_KeyDown, g_pplayer->m_rgKeys[ePlungerKey]); - // } - - // start the timer to send the corresponding KeyUp in 100ms - velocityData.AutoFireTimer = 101; - - } else if (velocityData.PullForce != 0.0f) { - // A "pull" force is in effect. This is a *simulated* pull, so - // it overrides the real physical plunger position. - // - // Simply update the model speed by applying the acceleration - // due to the pull force. - // - // Force = mass*acceleration -> a = F/m. Increase the speed - // by the acceleration. Technically we're calculating dv = a dt, - // but we can elide the elapsed time factor because it's - // effectively a constant that's implicitly folded into the - // pull force value. - movementData.Speed += velocityData.PullForce / VisualPinball.Engine.VPT.Plunger.Plunger.PlungerMass; - - if (!velocityData.AddRetractMotion) { - // this is the normal PullBack branch - - // if we're already at the maximum retracted position, stop - if (movementData.Position > staticData.FrameStart) { - movementData.Speed = 0.0f; - movementData.Position = staticData.FrameStart; - } - - // if we're already at the minimum retracted position, stop - if (movementData.Position < staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen) { - movementData.Speed = 0.0f; - movementData.Position = staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen; - } - - } else { - // this is the PullBackandRetract branch - - // after reaching the max. position the plunger should retract until it reaches the min. position and then start again - // if we're already at the maximum retracted position, reverse - if (movementData.Position >= staticData.FrameStart && velocityData.PullForce > 0) { - movementData.Speed = 0.0f; - movementData.Position = staticData.FrameStart; - velocityData.RetractWaitLoop++; - if (velocityData.RetractWaitLoop > 1000) { // 1 sec, related to PHYSICS_STEPTIME - velocityData.PullForce = -velocityData.InitialSpeed; - movementData.Position = staticData.FrameStart; - movementData.RetractMotion = true; - velocityData.RetractWaitLoop = 0; - } - } - - // if we're already at the minimum retracted position, start again - if (movementData.Position <= staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen && velocityData.PullForce <= 0) { - movementData.Speed = 0.0f; - velocityData.PullForce = velocityData.InitialSpeed; - movementData.Position = staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen; - } - - // reset retract motion indicator only after the rest position has been left, to avoid ball interactions - // use a linear pullback motion - if (movementData.Position > 1.0f + staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen && velocityData.PullForce > 0) { - movementData.RetractMotion = false; - movementData.Speed = 3.0f * velocityData.PullForce; // 3 = magic - } - } - - } else if (dMech > releaseThreshold) { - // Normal mode, fast forward motion detected. Consider this - // to be a release event. - // - // The release motion of a physical plunger is much faster - // than our sampling rate can keep up with, so we can't just - // use the joystick readings directly. The problem is that a - // real plunger can shoot all the way forward, bounce all the - // way back, and shoot forward again in the time between two - // consecutive samples. A real plunger moves at around 3-5m/s, - // which translates to 3-5mm/ms, or 30-50mm per 10ms sampling - // period. The whole plunger travel distance is ~65mm. - // So in one reading, we can travel almost the whole range! - // This means that samples are effectively random during a - // release motion. We might happen to get lucky and have - // our sample timing align perfectly with a release, so that - // we get one reading at the retracted position just before - // a release and the very next reading at the full forward - // position. Or we might get unlikely and catch one reading - // halfway down the initial initial lunge and the next reading - // at the very apex of the bounce back - and if we took those - // two readings at face value, we'd be fooled into thinking - // the plunger was stationary at the halfway point! - // - // But there's hope. A real plunger's barrel spring is pretty - // inelastic, so the rebounds after a release damp out quickly. - // Observationally, each bounce bounces back to less than half - // of the previous one. So even with the worst-case aliasing, - // we can be confident that we'll see a declining trend in the - // samples during a release-bounce-bounce-bounce sequence. - // - // Our detection strategy is simply to consider any rapid - // forward motion to be a release. If we see the plunger move - // forward by more than the threshold distance, we'll consider - // it a release. See the comments above for how we chose the - // threshold value. - - // Go back through the recent history to find the apex of the - // release. Our "threshold" calculation is basically attempting - // to measure the instantaneous speed of the plunger as the - // difference in position divided by the time interval. But - // the time interval is extremely imprecise, because joystick - // reports aren't synchronized to our clock. In practice the - // time between USB reports is in the 10-30ms range, which gives - // us a considerable range of error in calculating an instantaneous - // speed. - // - // So instead of relying on the instantaneous speed alone, now - // that we're pretty sure a release motion is under way, go back - // through our recent history to find out where it really - // started. Scan the history for monotonically ascending values, - // and take the highest one we find. That's probably where the - // user actually released the plunger. - var apex = velocityData.Mech0; - if (velocityData.Mech1 > apex) { - apex = velocityData.Mech1; - if (velocityData.Mech2 > apex) { - apex = velocityData.Mech2; - } - } - - // trigger a release from the apex position - PlungerCommands.Fire(apex, ref velocityData, ref movementData, in staticData); - - } else { - // Normal mode, and NOT firing the plunger. In this mode, we - // simply want to make the on-screen plunger sync up with the - // position of the physical plunger. - // - // This isn't as simple as just setting the software plunger's - // position to magically match that of the physical plunger. If - // we did that, we'd break the simulation by making the software - // plunger move at infinite speed. This wouldn't rip the fabric - // of space-time or anything that dire, but it *would* prevent - // the collision detection code from working properly. - // - // So instead, sync up the positions by setting the software - // plunger in motion on a course for syncing up with the - // physical plunger, as fast as we can while maintaining a - // realistic speed in the simulation. - - // for a normal plunger, sync to the mech plunger; otherwise - // just go to the rest position - var target = autoPlunger ? staticData.RestPosition : mech; - - // figure the current difference in positions - var error = target - pos; - - // Model the software plunger as though it were connected to the - // mechanical plunger by a spring with spring constant 'mech - // strength'. The force from a stretched spring is -kx (spring - // constant times displacement); in this case, the displacement - // is the distance between the physical and virtual plunger tip - // positions ('error'). The force from an acceleration is ma, - // so the acceleration from the spring force is -kx/m. Apply - // this acceleration to the current plunger speed. While we're - // at it, apply some damping to the current speed to simulate - // friction. - // - // The 'normalize' factor is the table's normalization constant - // divided by 1300, for historical reasons. Old versions applied - // a 1/13 adjustment factor, which appears to have been empirically - // chosen to get the speed in the right range. The m_plungerNormalize - // factor has default value 100 in this version, so we need to - // divide it by 100 to get a multipler value. - // - // The 'dt' factor represents the amount of time that we're applying - // this acceleration. This is in "VP 9 physics frame" units, where - // 1.0 equals the amount of real time in one VP 9 physics frame. - // The other normalization factors were originally chosen for VP 9 - // timing, so we need to adjust for the new VP 10 time base. VP 10 - // runs physics frames at roughly 10x the rate of VP 9, so the time - // per frame is about 1/10 the VP 9 time. - const float plungerFriction = 0.95f; - const float normalize = VisualPinball.Engine.VPT.Plunger.Plunger.PlungerNormalize / 13.0f / 100.0f; - const float dt = 0.1f; - movementData.Speed *= plungerFriction; - movementData.Speed += error * staticData.FrameLen * velocityData.MechStrength / VisualPinball.Engine.VPT.Plunger.Plunger.PlungerMass * normalize * dt; - - // add any reverse impulse to the result - movementData.Speed += movementData.ReverseImpulse; - } - - // cancel any reverse impulse - movementData.ReverseImpulse = 0.0f; - - // Shift the current mech reading into the history list, if it's - // different from the last reading. Only keep distinct readings; - // the physics loop tends to run faster than the USB reporting - // rate, so we might see the same USB report several times here. - if (mech != velocityData.Mech0) { - velocityData.Mech2 = velocityData.Mech1; - velocityData.Mech1 = velocityData.Mech0; - velocityData.Mech0 = mech; - } - - marker.End(); - - }).Run(); - } - } -} From 273cef4a63b4ec66b7762d9ebc6821b21e791068 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 9 Oct 2023 21:54:28 +0200 Subject: [PATCH 077/159] jobs: Migrate rest of contact system. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 2 +- .../Physics/Collision/ContactSystem.cs | 103 ++----------- .../SystemGroup/SimulateCycleSystemGroup.cs | 4 +- .../VPT/Ball/BallMovementSystem.cs | 136 ------------------ .../VPT/Ball/BallMovementSystem.cs.meta | 11 -- .../VPT/Spinner/SpinnerVelocityPhysics.cs | 5 +- 6 files changed, 19 insertions(+), 242 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index a3f80724f..927ba5a7a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -148,7 +148,7 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) for (var i = 0; i < _contacts.Length; i++) { ref var contact = ref _contacts.GetElementAsRef(i); ref var ball = ref state.Balls.GetValueByRef(contact.BallId); - BallCollider.HandleStaticContact(ref ball, in contact.CollEvent, state.Colliders.GetFriction(contact.CollEvent.ColliderId), hitTime, state.Env.Gravity); + ContactPhysics.Update(ref contact, ref ball, ref state, hitTime); } PerfMarkerContacts.End(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs index 5656f2c6d..db3c39dcf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs @@ -14,101 +14,28 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -// ReSharper disable ClassNeverInstantiated.Global - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -using Collider = UnityEngine.Collider; namespace VisualPinballUnity { - [DisableAutoCreation] - internal partial class ContactSystem : SystemBaseStub + internal static class ContactPhysics { - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - - private EntityQuery _collDataEntityQuery; - private float3 _gravity; - - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("ContactSystem"); - - protected override void OnCreate() - { - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - _collDataEntityQuery = EntityManager.CreateEntityQuery(typeof(ColliderData)); - } - - protected override void OnStartRunning() + internal static void Update(ref ContactBufferElement contact, ref BallData ball, ref PhysicsState state, float hitTime) { - _gravity = Object.FindObjectOfType().Gravity; - } - - protected override void OnUpdate() - { - var hitTime = _simulateCycleSystemGroup.HitTime; - var gravity = _gravity; - - // retrieve reference to static collider data - var collEntity = _collDataEntityQuery.GetSingletonEntity(); - var collData = EntityManager.GetComponentData(collEntity); - var contacts = _simulateCycleSystemGroup.Contacts; - var ballsLookup = GetComponentLookup(); - - var marker = PerfMarker; - - Job - .WithName("ContactJob") - .WithCode(() => - { - - marker.Begin(); - - ref var colliders = ref collData.Value.Value.Colliders; - - //if (rnd.NextBool()) { // swap order of contact handling randomly - for (var i = 0; i < contacts.Length; i++) { - - var contact = contacts[i]; - ref var collEvent = ref contact.CollEvent; - var ball = ballsLookup[Entity.Null]; // fixme jobs ballsLookup[contact.BallId]; - - if (collEvent.ColliderId > -1) { // collide with static collider - ref var coll = ref colliders[collEvent.ColliderId].Value; - unsafe { - fixed (VisualPinball.Unity.Collider* collider = &coll) { - - // flipper contact updates movement data - if (coll.Type == ColliderType.Flipper) { - - var flipperMovementData = GetComponent(coll.ItemId); - var flipperMaterialData = GetComponent(coll.ItemId); - var flipperVelocityData = GetComponent(coll.ItemId); - ((FlipperCollider*) collider)->Contact( - ref ball, ref flipperMovementData, in collEvent, - in flipperMaterialData, in flipperVelocityData, hitTime, in gravity); - SetComponent(coll.ItemId, flipperMovementData); - - } else { - VisualPinball.Unity.Collider.Contact(ref coll, ref ball, in collEvent, hitTime, in gravity); - } - } - } - - } else if (collEvent.BallId != 0) { // collide with ball - // todo move ball friction into some data component - BallCollider.HandleStaticContact(ref ball, in collEvent, 0.3f, hitTime, in gravity); - } - - ballsLookup[Entity.Null] = ball; // fixme jobs [contact.BallId] = ball; + ref var collEvent = ref contact.CollEvent; + if (collEvent.ColliderId > -1) { // collide with static collider + var coll = state.GetCollider(collEvent.ColliderId); + if (coll.Type == ColliderType.Flipper) { + ref var flipperCollider = ref state.Colliders.GetFlipperCollider(collEvent.ColliderId); + ref var flipperState = ref state.GetFlipperState(collEvent.ColliderId); + flipperCollider.Contact(ref ball, ref flipperState.Movement, in collEvent, + in flipperState.Static, in flipperState.Velocity, hitTime, in state.Env.Gravity); + } else { + Collider.Contact(ref coll, ref ball, in collEvent, hitTime, in state.Env.Gravity); } - - marker.End(); - - }).Run(); + } else if (collEvent.BallId != 0) { // collide with ball + BallCollider.HandleStaticContact(ref ball, in collEvent, state.Colliders.GetFriction(contact.CollEvent.ColliderId), hitTime, state.Env.Gravity); + } } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs index 9a6a08a4b..e54cb31d5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs @@ -56,7 +56,7 @@ internal partial class SimulateCycleSystemGroup : ComponentSystemGroup private UpdateDisplacementSystemGroup _displacementSystemGroup; private StaticCollisionSystem _staticCollisionSystem; private DynamicCollisionSystem _dynamicCollisionSystem; - private ContactSystem _contactSystem; + //private ContactSystem _contactSystem; private BallSpinHackSystem _ballSpinHackSystem; private float _staticCounts; @@ -143,7 +143,7 @@ private void UpdateCycle() _displacementSystemGroup.Update(); _dynamicCollisionSystem.Update(); _staticCollisionSystem.Update(); - _contactSystem.Update(); + //_contactSystem.Update(); ClearContacts(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs deleted file mode 100644 index 3d6008418..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs +++ /dev/null @@ -1,136 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -using Physics = UnityEngine.Physics; - -namespace VisualPinballUnity -{ - [AlwaysSynchronizeSystem] - [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class BallMovementSystem : SystemBaseStub - { - private float4x4 _baseTransform; - private Player _player; - - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallMovementSystem"); - - protected override void OnStartRunning() - { - var root = Object.FindObjectOfType(); - var ltw = root.gameObject.transform.localToWorldMatrix; - _baseTransform = new float4x4( - ltw.m00, ltw.m01, ltw.m02, ltw.m03, - ltw.m10, ltw.m11, ltw.m12, ltw.m13, - ltw.m20, ltw.m21, ltw.m22, ltw.m23, - ltw.m30, ltw.m31, ltw.m32, ltw.m33 - ); - _player = Object.FindObjectOfType(); - } - - protected override void OnUpdate() - { - var ltw = _baseTransform; - var marker = PerfMarker; - // fixme job - // Entities.WithoutBurst().WithName("BallMovementJob").ForEach((Entity entity, in BallData ball) => { - // - // marker.Begin(); - // - // if (!_player.Balls.ContainsKey(entity)) { - // marker.End(); - // return; - // } - // - // // calculate/adapt height of ball - // var zHeight = !ball.IsFrozen ? ball.Position.z : ball.Position.z - ball.Radius; - // var ballTransform = _player.Balls[entity].transform; - // ballTransform.localPosition = VisualPinball.Unity.Physics.TranslateToWorld(ball.Position.x, ball.Position.y, zHeight); - // - // var or = ball.BallOrientationForUnity; - // - // var VPX = new Vector3(or.c0.x, or.c1.x, or.c2.x); - // var VPY = new Vector3(or.c0.y, or.c1.y, or.c2.y); - // var VPZ = new Vector3(or.c0.z, or.c1.z, or.c2.z); - // - // // Debug.Log("c0: (" + or.c0.x + ", " + or.c0.y + ", " + or.c0.z + ")"); - // // Debug.Log("c1: (" + or.c1.x + ", " + or.c1.y + ", " + or.c1.z + ")"); - // // Debug.Log("c2: (" + or.c2.x + ", " + or.c2.y + ", " + or.c2.z + ")"); - // - // // for security reasons, so that we don't get NaN, NaN, NaN, NaN erroro, when vectors are not fully orthonormalized because of skewMatrix operation - // Vector3.OrthoNormalize(ref VPZ, ref VPY, ref VPX); - // - // Quaternion q = Quaternion.LookRotation(VPZ, VPY); - // - // // flip Z axis - // q = FlipZAxis(q); - // - // ballTransform.localRotation = q.RotateToWorld(); - // - // marker.End(); - // - // }).Run(); - - - static Quaternion FlipZAxis(Quaternion q) - { - // which actually flips x and y axis visually... - return new Quaternion(q.x, q.y, -q.z, -q.w); - } - - /* - * I let these two in here, just in case we need them. - - static float3x3 transpose(float3x3 or) - { - float3x3 or2; - or2.c0.x = or.c0.x; - or2.c0.y = or.c1.x; - or2.c0.z = or.c2.x; - or2.c1.x = or.c0.y; - or2.c1.y = or.c1.y; - or2.c1.z = or.c2.y; - or2.c2.x = or.c0.z; - or2.c2.y = or.c1.z; - or2.c2.z = or.c2.z; - return or2; - } - - static Quaternion QuaternionFromMatrix(Matrix4x4 m) - { - // Adapted from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm - Quaternion q = new Quaternion(); - q.w = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] + m[1, 1] + m[2, 2])) / 2; - q.x = Mathf.Sqrt(Mathf.Max(0, 1 + m[0, 0] - m[1, 1] - m[2, 2])) / 2; - q.y = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] + m[1, 1] - m[2, 2])) / 2; - q.z = Mathf.Sqrt(Mathf.Max(0, 1 - m[0, 0] - m[1, 1] + m[2, 2])) / 2; - q.x *= Mathf.Sign(q.x * (m[2, 1] - m[1, 2])); - q.y *= Mathf.Sign(q.y * (m[0, 2] - m[2, 0])); - q.z *= Mathf.Sign(q.z * (m[1, 0] - m[0, 1])); - return q; - } - - */ - - - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs.meta deleted file mode 100644 index 04c2fe918..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c37708d9a7a9dfe40a78b6fd1a5286ed -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs index f4fffb6f2..a5ec3c684 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs @@ -14,16 +14,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; -using Unity.Profiling; using VisualPinball.Engine.Common; using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; namespace VisualPinballUnity { - internal partial class SpinnerVelocityPhysics + internal static class SpinnerVelocityPhysics { internal static void UpdateVelocities(ref SpinnerMovementData movementData, in SpinnerStaticData data) { From 59a304e8c9c44e42c2619ece07eb59825d73dcb3 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 9 Oct 2023 22:50:10 +0200 Subject: [PATCH 078/159] jobs: Add ball spin hack. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 11 ++- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 7 ++ .../VisualPinball.Unity/Game/PhysicsState.cs | 2 + .../SystemGroup/SimulateCycleSystemGroup.cs | 4 +- .../VisualPinball.Unity/VPT/Ball/BallData.cs | 2 + .../BallLastPositionsBufferElement.cs.meta | 11 --- .../VPT/Ball/BallManager.cs | 19 ++-- .../VPT/Ball/BallPositions.cs | 86 +++++++++++++++++++ .../VPT/Ball/BallPositions.cs.meta | 3 + ...erElement.cs => BallRingCounterPhysics.cs} | 21 +++-- ...cs.meta => BallRingCounterPhysics.cs.meta} | 0 .../VPT/Ball/BallRingCounterSystem.cs | 50 ----------- .../VPT/Ball/BallSpinHackPhysics.cs | 49 +++++++++++ ...em.cs.meta => BallSpinHackPhysics.cs.meta} | 0 .../VPT/Ball/BallSpinHackSystem.cs | 57 ------------ .../VPT/Ball/BallVelocitySystem.cs | 68 --------------- .../VPT/Ball/BallVelocitySystem.cs.meta | 11 --- 17 files changed, 181 insertions(+), 220 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallPositions.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallPositions.cs.meta rename VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/{BallLastPositionsBufferElement.cs => BallRingCounterPhysics.cs} (59%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/{BallRingCounterSystem.cs.meta => BallRingCounterPhysics.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/{BallSpinHackSystem.cs.meta => BallSpinHackPhysics.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 927ba5a7a..f8f35fda1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -155,9 +155,14 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) // clear contacts _contacts.Clear(); - // todo ball spin hack - - dTime -= hitTime; + using (var enumerator = state.Balls.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var ball = ref enumerator.Current.Value; + BallSpinHackPhysics.Update(ref ball); + } + } + + dTime -= hitTime; } PerfMarker.End(); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index cc0cbc9ea..48d4fa2bf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -376,6 +376,13 @@ public void Execute() // primary physics loop cycle.Simulate(ref state, physicsDiffTime, timeMsec); + // ball trail, keep old pos of balls + using (var enumerator = state.Balls.GetEnumerator()) { + while (enumerator.MoveNext()) { + BallRingCounterPhysics.Update(ref enumerator.Current.Value); + } + } + #region Animation // bumper diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 6623f2932..3b368ed0b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -17,8 +17,10 @@ using NativeTrees; using Unity.Collections; using Unity.Entities; +using Unity.Mathematics; using VisualPinball.Engine.VPT; using VisualPinball.Unity.Collections; +using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs index e54cb31d5..4164638b9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs @@ -57,7 +57,7 @@ internal partial class SimulateCycleSystemGroup : ComponentSystemGroup private StaticCollisionSystem _staticCollisionSystem; private DynamicCollisionSystem _dynamicCollisionSystem; //private ContactSystem _contactSystem; - private BallSpinHackSystem _ballSpinHackSystem; + //private BallSpinHackPhysics _ballSpinHackPhysics; private float _staticCounts; private EntityQuery _flipperDataQuery; @@ -147,7 +147,7 @@ private void UpdateCycle() ClearContacts(); - _ballSpinHackSystem.Update(); + //_ballSpinHackPhysics.Update(); dTime -= HitTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs index d3425e83f..f40012ef6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs @@ -63,6 +63,8 @@ internal struct BallData : IComponentData public CollisionEventData CollisionEvent; + public BallPositions LastPositions; + public Aabb Aabb { get { var vl = math.length(Velocity) + Radius + 0.05f; // 0.05f = paranoia diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs.meta deleted file mode 100644 index a1f183f56..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b2421e157d48a764b8adcb466202489b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index ce38ec817..5618a86a3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -88,7 +88,7 @@ public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float typeof(OverlappingStaticColliderBufferElement), typeof(OverlappingDynamicBufferElement), typeof(BallInsideOfBufferElement), - typeof(BallLastPositionsBufferElement), + //typeof(BallLastPositionsBufferElement), typeof(BallData), typeof(CollisionEventData) ); @@ -117,7 +117,8 @@ public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float BallOrientation = float3x3.identity, BallOrientationForUnity = float3x3.identity, RingCounterOldPos = 0, - AngularMomentum = float3.zero + AngularMomentum = float3.zero, + LastPositions = new BallPositions(new float3(float.MaxValue, float.MaxValue, float.MaxValue)) }); ecb.AddComponent(entity, new CollisionEventData { @@ -127,13 +128,13 @@ public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float IsContact = false, HitNormal = new float3(0, 0, 0), }); - - var lastBallPostBuffer = ecb.AddBuffer(entity); - for (var i = 0; i < BallRingCounterSystem.MaxBallTrailPos; i++) { - lastBallPostBuffer.Add(new BallLastPositionsBufferElement - { Value = new float3(float.MaxValue, float.MaxValue, float.MaxValue) } - ); - } + // + // var lastBallPostBuffer = ecb.AddBuffer(entity); + // for (var i = 0; i < BallRingCounterPhysics.MaxBallTrailPos; i++) { + // lastBallPostBuffer.Add(new BallLastPositionsBufferElement + // { Value = new float3(float.MaxValue, float.MaxValue, float.MaxValue) } + // ); + // } // handle inside-kicker creation if (kickerId != 0) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallPositions.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallPositions.cs new file mode 100644 index 000000000..29efcf518 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallPositions.cs @@ -0,0 +1,86 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using Unity.Mathematics; + +namespace VisualPinball.Unity +{ + /// + /// We can't have lists of lists in jobs, so... + /// + public struct BallPositions + { + public static int Count => 10; + + private float3 _pos00; + private float3 _pos01; + private float3 _pos02; + private float3 _pos03; + private float3 _pos04; + private float3 _pos05; + private float3 _pos06; + private float3 _pos07; + private float3 _pos08; + private float3 _pos09; + + public BallPositions(float3 initialPositions) + { + _pos00 = initialPositions; + _pos01 = initialPositions; + _pos02 = initialPositions; + _pos03 = initialPositions; + _pos04 = initialPositions; + _pos05 = initialPositions; + _pos06 = initialPositions; + _pos07 = initialPositions; + _pos08 = initialPositions; + _pos09 = initialPositions; + } + + public float3 this[int index] { + get { + return index switch { + 0 => _pos00, + 1 => _pos01, + 2 => _pos02, + 3 => _pos03, + 4 => _pos04, + 5 => _pos05, + 6 => _pos06, + 7 => _pos07, + 8 => _pos08, + 9 => _pos09, + _ => throw new ArgumentOutOfRangeException("Only " + Count + " positions available.") + }; + } + set { + switch (index) { + case 0: _pos00 = value; break; + case 1: _pos01 = value; break; + case 2: _pos02 = value; break; + case 3: _pos03 = value; break; + case 4: _pos04 = value; break; + case 5: _pos05 = value; break; + case 6: _pos06 = value; break; + case 7: _pos07 = value; break; + case 8: _pos08 = value; break; + case 9: _pos09 = value; break; + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallPositions.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallPositions.cs.meta new file mode 100644 index 000000000..fb3544d8e --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallPositions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 01112e733aac4619b2c5d14fc90a2064 +timeCreated: 1696882763 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterPhysics.cs similarity index 59% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterPhysics.cs index 98df7d768..f8146f2c8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallLastPositionsBufferElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterPhysics.cs @@ -14,17 +14,20 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; -using Unity.Mathematics; +using VisualPinball.Engine.Common; -namespace VisualPinballUnity +namespace VisualPinball.Unity { - /// - /// The ball's last positions - /// - [InternalBufferCapacity(BallRingCounterSystem.MaxBallTrailPos)] - internal struct BallLastPositionsBufferElement : IBufferElementData + internal static class BallRingCounterPhysics { - public float3 Value; + internal static void Update(ref BallData ball) + { + var idx = ball.RingCounterOldPos / (10000 / PhysicsConstants.PhysicsStepTime); + ball.LastPositions[idx] = ball.Position; + ball.RingCounterOldPos++; + if (ball.RingCounterOldPos == BallPositions.Count * (10000 / PhysicsConstants.PhysicsStepTime)) { + ball.RingCounterOldPos = 0; + } + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterPhysics.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs deleted file mode 100644 index 732c28a48..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterSystem.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using VisualPinball.Engine.Common; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal partial class BallRingCounterSystem : SystemBaseStub - { - public const int MaxBallTrailPos = 10; - - protected override void OnUpdate() - { - var lastPositionBuffer = GetBufferLookup(); - Entities - .WithNativeDisableParallelForRestriction(lastPositionBuffer) - .ForEach((Entity entity, ref BallData ball) => - { - var posIdx = ball.RingCounterOldPos / (10000 / PhysicsConstants.PhysicsStepTime); - var lastPositions = lastPositionBuffer[entity]; - var lastPosition = lastPositions[posIdx]; - lastPosition.Value = ball.Position; - lastPositions[posIdx] = lastPosition; - - ball.RingCounterOldPos++; - if (ball.RingCounterOldPos == MaxBallTrailPos * (10000 / PhysicsConstants.PhysicsStepTime)) { - ball.RingCounterOldPos = 0; - } - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs new file mode 100644 index 000000000..64fe0eb99 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs @@ -0,0 +1,49 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Entities; +using Unity.Mathematics; +using VisualPinball.Engine.Common; +using VisualPinball.Unity; + +// ReSharper disable CompareOfFloatsByEqualityOperator + +namespace VisualPinballUnity +{ + [DisableAutoCreation] + internal static class BallSpinHackPhysics + { + internal static void Update(ref BallData ball) + { + var p0 = (ball.RingCounterOldPos / (10000 / PhysicsConstants.PhysicsStepTime) + 1) % BallPositions.Count; + var p1 = (ball.RingCounterOldPos / (10000 / PhysicsConstants.PhysicsStepTime) + 2) % BallPositions.Count; + + // only if already initialized + if (ball.CollisionEvent.HitDistance < PhysicsConstants.PhysTouch && ball.LastPositions[p0].x != Constants.FloatMax && ball.LastPositions[p1].x != float.MaxValue) { + var diffPos = ball.LastPositions[p0] - ball.Position; + var mag = diffPos.x*diffPos.x + diffPos.y*diffPos.y; + var diffPos2 = ball.LastPositions[p1] - ball.Position; + var mag2 = diffPos2.x*diffPos2.x + diffPos2.y*diffPos2.y; + var threshold = (ball.AngularMomentum.x*ball.AngularMomentum.x + ball.AngularMomentum.y*ball.AngularMomentum.y) / math.max(mag, mag2); + + if (!float.IsNaN(threshold) && !float.IsInfinity(threshold) && threshold > 666) { + var damp = math.clamp(1.0f - (threshold - 666) / 10000, 0.23f, 1); // do not kill spin completely, otherwise stuck balls will happen during regular gameplay + ball.AngularMomentum *= damp; + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs deleted file mode 100644 index f04a49b4b..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackSystem.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; -using VisualPinball.Engine.Common; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal partial class BallSpinHackSystem : SystemBaseStub - { - protected override void OnUpdate() - { - var lastPositionBuffer = GetBufferLookup(true); - Entities - .WithReadOnly(lastPositionBuffer) - .ForEach((Entity entity, ref BallData ball, in CollisionEventData collEvent) => - { - - var lastPos = lastPositionBuffer[entity]; - var p0 = (ball.RingCounterOldPos / (10000 / PhysicsConstants.PhysicsStepTime) + 1) % BallRingCounterSystem.MaxBallTrailPos; - var p1 = (ball.RingCounterOldPos / (10000 / PhysicsConstants.PhysicsStepTime) + 2) % BallRingCounterSystem.MaxBallTrailPos; - - // only if already initialized - if (collEvent.HitDistance < PhysicsConstants.PhysTouch && lastPos[p0].Value.x != Constants.FloatMax && lastPos[p1].Value.x != float.MaxValue) { - var diffPos = lastPos[p0].Value - ball.Position; - var mag = diffPos.x*diffPos.x + diffPos.y*diffPos.y; - var diffPos2 = lastPos[p1].Value - ball.Position; - var mag2 = diffPos2.x*diffPos2.x + diffPos2.y*diffPos2.y; - var threshold = (ball.AngularMomentum.x*ball.AngularMomentum.x + ball.AngularMomentum.y*ball.AngularMomentum.y) / math.max(mag, mag2); - - if (!float.IsNaN(threshold) && !float.IsInfinity(threshold) && threshold > 666) { - var damp = math.clamp(1.0f - (threshold - 666) / 10000, 0.23f, 1); // do not kill spin completely, otherwise stuck balls will happen during regular gameplay - ball.AngularMomentum *= damp; - } - } - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs deleted file mode 100644 index c6110c7b0..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable CompareOfFloatsByEqualityOperator - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Engine.Common; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - internal partial class BallVelocitySystem : SystemBaseStub - { - private float3 _gravity; - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallVelocitySystem"); - - protected override void OnStartRunning() - { - _gravity = Object.FindObjectOfType().Gravity; - } - - protected override void OnUpdate() - { - var gravity = _gravity; - var marker = PerfMarker; - Entities.WithName("BallVelocityJob").ForEach((ref BallData ball) => { - - if (ball.IsFrozen) { - return; - } - - marker.Begin(); - - if (ball.ManualControl) { - ball.Velocity *= 0.5f; // Null out most of the X/Y velocity, want a little bit so the ball can sort of find its way out of obstacles. - ball.Velocity += new float3( - math.max(-10.0f, math.min(10.0f, (ball.ManualPosition.x - ball.Position.x) * (float)(1.0/10.0))), - math.max(-10.0f, math.min(10.0f, (ball.ManualPosition.y - ball.Position.y) * (float)(1.0/10.0))), - -2.0f - ); - } else { - ball.Velocity += gravity * (float)PhysicsConstants.PhysFactor; - } - - marker.End(); - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs.meta deleted file mode 100644 index 527312329..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocitySystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: aa2bbeac528b2614e96ff611feea8491 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From 505ca3f93089094f63d115700486d0f5022eaeab Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 9 Oct 2023 23:16:27 +0200 Subject: [PATCH 079/159] jobs: Migrate hit- and drop targets, and clean up some obsolete systems. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 44 +++ .../VisualPinball.Unity/Game/PhysicsState.cs | 2 - .../Collision/StaticBroadPhaseSystem.cs | 67 ---- .../Collision/StaticBroadPhaseSystem.cs.meta | 11 - .../Collision/StaticCollisionSystem.cs | 311 ------------------ .../Collision/StaticCollisionSystem.cs.meta | 11 - .../Collision/StaticNarrowPhaseSystem.cs | 213 ------------ .../Collision/StaticNarrowPhaseSystem.cs.meta | 11 - .../CreateBallEntityCommandBufferSystem.cs | 26 -- ...reateBallEntityCommandBufferSystem.cs.meta | 11 - .../SystemGroup/SimulateBuildSystem.cs | 1 - .../SystemGroup/SimulateCycleSystemGroup.cs | 16 +- .../SystemGroup/TransformMeshesSystemGroup.cs | 25 -- .../TransformMeshesSystemGroup.cs.meta | 11 - .../UpdateAnimationsSystemGroup.cs | 26 -- .../UpdateAnimationsSystemGroup.cs.meta | 11 - .../UpdateDisplacementSystemGroup.cs | 25 -- .../UpdateDisplacementSystemGroup.cs.meta | 11 - .../UpdateVelocitiesSystemGroup.cs | 25 -- .../UpdateVelocitiesSystemGroup.cs.meta | 11 - .../VPT/Ball/BallDisplacementSystem.cs | 111 ------- .../VPT/Ball/BallDisplacementSystem.cs.meta | 11 - .../VPT/Ball/BallManager.cs | 56 ++-- .../VPT/Flipper/FlipperDisplacementSystem.cs | 130 -------- .../Flipper/FlipperDisplacementSystem.cs.meta | 11 - .../VPT/Flipper/FlipperRotateSystem.cs | 55 ---- .../VPT/Flipper/FlipperRotateSystem.cs.meta | 11 - .../VPT/Flipper/FlipperVelocitySystem.cs | 192 ----------- .../VPT/Flipper/FlipperVelocitySystem.cs.meta | 11 - .../VPT/HitTarget/DropTargetAnimation.cs | 76 +++++ ...em.cs.meta => DropTargetAnimation.cs.meta} | 0 .../HitTarget/DropTargetAnimationSystem.cs | 119 ------- .../DropTargetTransformationSystem.cs | 58 ---- .../DropTargetTransformationSystem.cs.meta | 11 - .../VPT/HitTarget/HitTargetAnimation.cs | 58 ++++ ...tem.cs.meta => HitTargetAnimation.cs.meta} | 0 .../VPT/HitTarget/HitTargetAnimationSystem.cs | 91 ----- .../HitTargetTransformationSystem.cs | 58 ---- .../HitTargetTransformationSystem.cs.meta | 11 - 39 files changed, 214 insertions(+), 1725 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/{DropTargetAnimationSystem.cs.meta => DropTargetAnimation.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimation.cs rename VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/{HitTargetAnimationSystem.cs.meta => HitTargetAnimation.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 48d4fa2bf..c1af9877e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -229,6 +229,34 @@ private void Update() } } + // drop targets + using (var enumerator = _dropTargetStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var dropTargetState = ref enumerator.Current.Value; + var dropTargetTransform = _transforms[dropTargetState.AnimatedItemId]; + var localPos = dropTargetTransform.localPosition; + dropTargetTransform.localPosition = new Vector3( + localPos.x, + Physics.ScaleToWorld(dropTargetState.Animation.ZOffset), + localPos.z + ); + } + } + + // hit targets + using (var enumerator = _hitTargetStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var hitTargetState = ref enumerator.Current.Value; + var hitTargetTransform = _transforms[hitTargetState.AnimatedItemId]; + var localRot = hitTargetTransform.localEulerAngles; + hitTargetTransform.localEulerAngles = new Vector3( + hitTargetState.Animation.XRotation, + localRot.y, + localRot.z + ); + } + } + // gates using (var enumerator = _gateStates.GetEnumerator()) { while (enumerator.MoveNext()) { @@ -398,6 +426,22 @@ public void Execute() } } + // drop target + using (var enumerator = DropTargetStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var dropTargetState = ref enumerator.Current.Value; + DropTargetAnimation.Update(enumerator.Current.Key, ref dropTargetState.Animation, in dropTargetState.Static, ref state, timeMsec); + } + } + + // hit target + using (var enumerator = HitTargetStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var hitTargetState = ref enumerator.Current.Value; + HitTargetAnimation.Update(ref hitTargetState.Animation, in hitTargetState.Static, timeMsec); + } + } + // plunger using (var enumerator = PlungerStates.GetEnumerator()) { while (enumerator.MoveNext()) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 3b368ed0b..6623f2932 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -17,10 +17,8 @@ using NativeTrees; using Unity.Collections; using Unity.Entities; -using Unity.Mathematics; using VisualPinball.Engine.VPT; using VisualPinball.Unity.Collections; -using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs deleted file mode 100644 index 72b34809e..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Profiling; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal partial class StaticBroadPhaseSystem : SystemBaseStub - { - private EntityQuery _quadTreeEntityQuery; - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("StaticBroadPhaseSystem"); - - protected override void OnCreate() - { - _quadTreeEntityQuery = EntityManager.CreateEntityQuery(typeof(QuadTreeData)); - _simulateCycleSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); - } - - protected override void OnUpdate() - { - // retrieve reference to static quad tree data - var collEntity = _quadTreeEntityQuery.GetSingletonEntity(); - var collData = EntityManager.GetComponentData(collEntity); - var itemsColliding = _simulateCycleSystemGroup.ItemsColliding; - var marker = PerfMarker; - - Entities - .WithName("StaticBroadPhaseJob") - .WithReadOnly(itemsColliding) - .ForEach((ref DynamicBuffer colliderIds, in BallData ballData) => { - - // don't play with frozen balls - if (ballData.IsFrozen) { - return; - } - - marker.Begin(); - - ref var quadTree = ref collData.Value.Value.QuadTree; - colliderIds.Clear(); - quadTree.GetAabbOverlaps(in ballData, in itemsColliding, ref colliderIds); - - marker.End(); - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs.meta deleted file mode 100644 index ba72cdb22..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticBroadPhaseSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 08e7bd65c999ea745a459ca73b26e86b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs deleted file mode 100644 index 88018d4a9..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs +++ /dev/null @@ -1,311 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable ConvertIfStatementToSwitchStatement - -using System; -using Unity.Collections; -using Unity.Entities; -using Unity.Profiling; -using VisualPinball.Engine.VPT; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -using Object = UnityEngine.Object; -using Random = UnityEngine.Random; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal partial class StaticCollisionSystem : SystemBaseStub - { - private Player _player; - private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - private EntityQuery _collDataEntityQuery; - private NativeQueue _eventQueue; - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("StaticCollisionSystem"); - - protected override void OnCreate() - { - _visualPinballSimulationSystemGroup = World.GetOrCreateSystemManaged(); - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - _collDataEntityQuery = EntityManager.CreateEntityQuery(typeof(ColliderData)); - _eventQueue = new NativeQueue(Allocator.Persistent); - } - - protected override void OnStartRunning() - { - _player = Object.FindObjectOfType(); - } - - protected override void OnDestroy() - { - _eventQueue.Dispose(); - } - - protected override void OnUpdate() - { - // retrieve reference to static collider data - var collEntity = _collDataEntityQuery.GetSingletonEntity(); - var collData = EntityManager.GetComponentData(collEntity); - var random = new global::Unity.Mathematics.Random((uint)Random.Range(1, 100000)); - - var events = _eventQueue.AsParallelWriter(); - - var hitTime = _simulateCycleSystemGroup.HitTime; - var timeMsec = _visualPinballSimulationSystemGroup.TimeMsec; - var marker = PerfMarker; - - Entities - .WithName("StaticCollisionJob") - .ForEach((Entity ballEntity, ref BallData ballData, ref CollisionEventData collEvent, - ref DynamicBuffer insideOfs) => { - - var ballId = 0; - // find balls with hit objects and minimum time - if (collEvent.ColliderId < 0 || collEvent.HitTime > hitTime) { - return; - } - - marker.Begin(); - - // retrieve static data - ref var colliders = ref collData.Value.Value.Colliders; - - // pick collider that matched during narrowphase - ref var coll = ref colliders[collEvent.ColliderId].Value; // object that ball hit in trials - - // now collision, contact and script reactions on active ball (object)+++++++++ - - //this.activeBall = ball; // For script that wants the ball doing the collision - - unsafe { - fixed (Collider* collider = &coll) { - - switch (coll.Type) { - case ColliderType.Bumper: { - // var bumperStaticData = GetComponent(coll.ItemId); - // var animateRing = HasComponent(coll.ItemId); - // var animateSkirt = HasComponent(coll.ItemId); - // var ringData = animateRing ? GetComponent(coll.ItemId) : default; - // var skirtData = animateSkirt ? GetComponent(coll.ItemId): default; - // BumperCollider.Collide(ref ballData, ref events, ref collEvent, ref ringData, ref skirtData, - // in coll, bumperStaticData, ref random); - // if (animateRing) { - // SetComponent(coll.ItemId, ringData); - // } - // if (animateSkirt) { - // SetComponent(coll.ItemId, skirtData); - // } - break; - } - - case ColliderType.Flipper: { - var flipperVelocityData = GetComponent(coll.ItemId); - var flipperMovementData = GetComponent(coll.ItemId); - var flipperMaterialData = GetComponent(coll.ItemId); - var flipperHitData = GetComponent(coll.ItemId); - var flipperTricksData = GetComponent(coll.ItemId); - // do liveCatch - check before collision - FlipperCollider.LiveCatch( - ref ballData, ref collEvent, ref flipperTricksData, in flipperMaterialData, timeMsec - ); - ((FlipperCollider*)collider)->Collide( - ref ballData, ref collEvent, ref flipperMovementData, ref events, - in ballId, in flipperTricksData,in flipperMaterialData, in flipperVelocityData, in flipperHitData, timeMsec - ); - SetComponent(coll.ItemId, flipperMovementData); - break; - } - - case ColliderType.Gate: { - // var gateStaticData = GetComponent(coll.ItemId); - // var gateMovementData = GetComponent(coll.ItemId); - // GateCollider.Collide( - // ref ballData, ref collEvent, ref gateMovementData, ref events, - // in ballId, in coll, in gateStaticData - // ); - // SetComponent(coll.ItemId, gateMovementData); - break; - } - - case ColliderType.LineSlingShot: { - // var slingshotData = GetComponent(coll.ItemId); - // ((LineSlingshotCollider*)collider)->Collide( - // ref ballData, ref events, - // in ballId, in slingshotData, in collEvent, ref random); - break; - } - - case ColliderType.Plunger: { - // var plungerMovementData = GetComponent(coll.ItemId); - // var plungerStaticData = GetComponent(coll.ItemId); - // PlungerCollider.Collide( - // ref ballData, ref collEvent, ref plungerMovementData, - // in plungerStaticData, ref random); - // SetComponent(coll.ItemId, plungerMovementData); - break; - } - - case ColliderType.Spinner: { - // var spinnerStaticData = GetComponent(coll.ItemId); - // var spinnerMovementData = GetComponent(coll.ItemId); - // SpinnerCollider.Collide( - // in ballData, ref collEvent, ref spinnerMovementData, - // in spinnerStaticData - // ); - // SetComponent(coll.ItemId, spinnerMovementData); - break; - } - - case ColliderType.TriggerCircle: - case ColliderType.TriggerLine: { - - // var triggerAnimationData = HasComponent(coll.ItemId) - // ? GetComponent(coll.ItemId) - // : new TriggerAnimationData(); - - // TriggerCollider.Collide( - // ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, - // in ballId, in coll - // ); - - // if (HasComponent(coll.ItemId)) { - // if (triggerAnimationData.UnHitEvent) { - // var flipperCorrectionData = GetComponent(coll.ItemId); - // ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; - // var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // var flipperTricksData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // FlipperCorrection.OnBallLeaveFlipper( - // ref ballData, ref flipperCorrectionBlob, in flipperMovementData, in flipperTricksData, in flipperStaticData, timeMsec - // ); - // } - // - // } else { - // SetComponent(coll.ItemId, triggerAnimationData); - // } - break; - } - - case ColliderType.KickerCircle: { - // var kickerCollisionData = GetComponent(coll.ItemId); - // var kickerStaticData = GetComponent(coll.ItemId); - // // ReSharper disable once ConditionIsAlwaysTrueOrFalse - // var legacyMode = KickerCollider.ForceLegacyMode || kickerStaticData.LegacyMode; - // // ReSharper disable once ConditionIsAlwaysTrueOrFalse - // var kickerMeshData = !legacyMode ? GetComponent(coll.ItemId) : default; - // // KickerCollider.Collide(ref ballData, ref events, ref insideOfs, ref kickerCollisionData, - // // in kickerStaticData, in kickerMeshData, in collEvent, coll.ItemId, in ballId - // // ); - // SetComponent(coll.ItemId, kickerCollisionData); - break; - } - - case ColliderType.Line: - case ColliderType.Line3D: - case ColliderType.Circle: - case ColliderType.LineZ: - case ColliderType.Plane: - case ColliderType.Point: - case ColliderType.Triangle: - - // // hit target - // if (coll.Header.ItemType == ItemType.HitTarget) { - // - // var normal = coll.Type == ColliderType.Triangle - // ? ((TriangleCollider*) collider)->Normal() - // : collEvent.HitNormal; - // - // if (HasComponent(coll.ItemId)) { - // var dropTargetAnimationData = GetComponent(coll.ItemId); - // TargetCollider.DropTargetCollide(ref ballData, ref events, ref dropTargetAnimationData, - // in normal, in ballId, in collEvent, in coll, ref random); - // SetComponent(coll.ItemId, dropTargetAnimationData); - // } - // - // if (HasComponent(coll.ItemId)) { - // var hitTargetAnimationData = GetComponent(coll.ItemId); - // TargetCollider.HitTargetCollide(ref ballData, ref events, ref hitTargetAnimationData, - // in normal, in ballId, in collEvent, in coll, ref random); - // SetComponent(coll.ItemId, hitTargetAnimationData); - // } - // - // // trigger - // } else if (coll.Header.ItemType == ItemType.Trigger) { - // - // var triggerAnimationData = HasComponent(coll.ItemId) - // ? GetComponent(coll.ItemId) - // : new TriggerAnimationData(); - // - // // TriggerCollider.Collide( - // // ref ballData, ref events, ref collEvent, ref insideOfs, ref triggerAnimationData, - // // in ballId, in coll - // // ); - // - // if (HasComponent(coll.ItemId)) { - // if (triggerAnimationData.UnHitEvent) { - // var flipperCorrectionData = GetComponent(coll.ItemId); - // ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; - // var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // var flipperTricksData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // FlipperCorrection.OnBallLeaveFlipper( - // ref ballData, ref flipperCorrectionBlob, in flipperMovementData, in flipperTricksData, in flipperStaticData, timeMsec - // ); - // } - // - // } else { - // SetComponent(coll.ItemId, triggerAnimationData); - // } - // - // } else { - // Collider.Collide(in coll, ref ballData, ref events, in ballId, in collEvent, ref random); - // } - break; - - case ColliderType.None: - default: - throw new ArgumentOutOfRangeException(); - } - } - } - - // remove trial hit object pointer - collEvent.ClearCollider(); - - // todo fix below (probably just delete) - // Collide may have changed the velocity of the ball, - // and therefore the bounding box for the next hit cycle - // if (this.balls[i] !== ball) { // Ball still exists? may have been deleted from list - // - // // collision script deleted the ball, back up one count - // --i; - // - // } else { - // ball.hit.calcHitBBox(); // do new boundings - // } - - marker.End(); - - }).Run(); - - while (_eventQueue.TryDequeue(out var eventData)) { - _player.OnEvent(eventData); - } - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs.meta deleted file mode 100644 index a78e2df8f..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticCollisionSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 12d011021080560428d30ceae7d677cc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs deleted file mode 100644 index f0ef22dc1..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs +++ /dev/null @@ -1,213 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Collections; -using Unity.Entities; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -using Collider = VisualPinball.Unity.Collider; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal partial class StaticNarrowPhaseSystem : SystemBaseStub - { - public bool CollideAgainstPlayfieldPlane; - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - private EntityQuery _collDataEntityQuery; - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("StaticNarrowPhaseSystem"); - - protected override void OnCreate() - { - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - _collDataEntityQuery = EntityManager.CreateEntityQuery(typeof(ColliderData)); - } - - protected override void OnUpdate() - { - // retrieve reference to static collider data - var collideAgainstPlayfieldPlane = CollideAgainstPlayfieldPlane; - var collEntity = _collDataEntityQuery.GetSingletonEntity(); - var collData = EntityManager.GetComponentData(collEntity); - var contacts = _simulateCycleSystemGroup.Contacts; - var hitTime = _simulateCycleSystemGroup.HitTime; - var random = new Unity.Mathematics.Random((uint)Random.Range(1, 100000)); - var marker = PerfMarker; - - Entities - .WithName("StaticNarrowPhaseJob") - .ForEach((Entity ballEntity, ref CollisionEventData collEvent, - ref DynamicBuffer insideOfs, - in DynamicBuffer colliderIds, in BallData ballData) => - { - - // don't play with frozen balls - if (ballData.IsFrozen) { - return; - } - - marker.Begin(); - - // retrieve static data - ref var colliders = ref collData.Value.Value.Colliders; - - // init contacts and event - collEvent.ClearCollider(hitTime); // search upto current hit time - - // check playfield and glass first - if (collideAgainstPlayfieldPlane) { - ref var playfieldCollider = ref colliders[collData.Value.Value.PlayfieldColliderId].Value; - HitTest(ref playfieldCollider, ref collEvent, ref contacts, ref insideOfs, in ballData.Id, in ballData); - } - ref var glassCollider = ref colliders[collData.Value.Value.GlassColliderId].Value; - HitTest(ref glassCollider, ref collEvent, ref contacts, ref insideOfs, in ballData.Id, in ballData); - - var traversalOrder = false; //random.NextBool(); - var start = traversalOrder ? 0 : colliderIds.Length - 1; - var end = traversalOrder ? colliderIds.Length : -1; - var dt = traversalOrder ? 1 : -1; - - - for (var i = start; i != end; i += dt) { - ref var coll = ref colliders[colliderIds[i].Value].Value; - var saveCollision = true; - - var newCollEvent = new CollisionEventData(); - float newTime = 0; - unsafe { - fixed (Collider* collider = &coll) { - switch (coll.Type) { - - case ColliderType.LineSlingShot: -// newTime = ((LineSlingshotCollider*) collider)->HitTest(ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); - break; - - case ColliderType.Flipper: - if (HasComponent(coll.ItemId) && - HasComponent(coll.ItemId) && - HasComponent(coll.ItemId)) - { - var flipperHitData = GetComponent(coll.ItemId); - var flipperMovementData = GetComponent(coll.ItemId); - var flipperMaterialData = GetComponent(coll.ItemId); - var flipperTricksData = GetComponent(coll.ItemId); - // newTime = ((FlipperCollider*)collider)->HitTest( - // ref newCollEvent, ref insideOfs, ref flipperHitData, - // in flipperMovementData, in flipperTricksData, in flipperMaterialData, in ballData, collEvent.HitTime - // ); - - SetComponent(coll.ItemId, flipperHitData); - } - break; - - case ColliderType.Plunger: - // if (HasComponent(coll.ItemId) && - // HasComponent(coll.ItemId) && - // HasComponent(coll.ItemId)) - // { - // var plungerColliderData = GetComponent(coll.ItemId); - // var plungerStaticData = GetComponent(coll.ItemId); - // var plungerMovementData = GetComponent(coll.ItemId); - // // newTime = ((PlungerCollider*)collider)->HitTest( - // // ref newCollEvent, ref insideOfs, ref plungerMovementData, - // // in plungerColliderData, in plungerStaticData, in ballData, collEvent.HitTime - // // ); - // - // SetComponent(coll.ItemId, plungerMovementData); - // } - break; - case ColliderType.Line: - case ColliderType.Line3D: - case ColliderType.Circle: - case ColliderType.LineZ: - case ColliderType.Plane: - case ColliderType.Point: - case ColliderType.Triangle: - // // hit target - // if (coll.Header.ItemType == ItemType.HitTarget) { - // if (HasComponent(coll.ItemId)) { - // var dropTargetAnimationData = GetComponent(coll.ItemId); - // if (dropTargetAnimationData.IsDropped || dropTargetAnimationData.MoveAnimation) { // QUICKFIX so that DT is not triggered twice - // saveCollision = false; - // } - // else { - // newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); - // } - // } - // if (HasComponent(coll.ItemId)) { - // newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); - // } - // } - // else - // newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); - break; - - default: - newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); - break; - } - } - } - if (saveCollision) { - SaveCollisions(ref collEvent, ref newCollEvent, ref contacts, in ballData.Id, in coll, newTime); - } - } - - // no negative time allowed - if (collEvent.HitTime < 0) { - collEvent.ClearCollider(); - } - - marker.End(); - - }).Run(); - } - - private static void HitTest(ref Collider coll, ref CollisionEventData collEvent, - ref NativeList contacts, ref DynamicBuffer insideOfs, - in int ballId, in BallData ballData) { - - // todo - // if (collider.obj && collider.obj.abortHitTest && collider.obj.abortHitTest()) { - // return; - // } - - var newCollEvent = new CollisionEventData(); - var newTime = Collider.HitTest(ref coll, ref newCollEvent, ref insideOfs, in ballData, collEvent.HitTime); - - SaveCollisions(ref collEvent, ref newCollEvent, ref contacts, in ballId, in coll, newTime); - } - - private static void SaveCollisions(ref CollisionEventData collEvent, ref CollisionEventData newCollEvent, - ref NativeList contacts, in int ballId, in Collider coll, float newTime) - { - var validHit = newTime >= 0f && !Math.Sign(newTime) && newTime <= collEvent.HitTime; - - if (newCollEvent.IsContact || validHit) { - newCollEvent.SetCollider(coll.Id); - newCollEvent.HitTime = newTime; - if (newCollEvent.IsContact) { - contacts.Add(new ContactBufferElement(ballId, newCollEvent)); - - } else { // if (validhit) - collEvent = newCollEvent; - } - } - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs.meta deleted file mode 100644 index 349e12fb5..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/StaticNarrowPhaseSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 61f4dfd573c4cb3408beb5297105d11b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs deleted file mode 100644 index a7e124867..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal class CreateBallEntityCommandBufferSystem : EntityCommandBufferSystem - { - - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs.meta deleted file mode 100644 index ea29d107f..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/CreateBallEntityCommandBufferSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6966183f5f8a87a4dae27aebfc2f120e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs index 1f3818c13..3695731b2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs @@ -23,7 +23,6 @@ namespace VisualPinballUnity { - [UpdateBefore(typeof(TransformMeshesSystemGroup))] internal partial class SimulateBuildSystem : SystemBaseStub { private float4x4 _baseTransform; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs index 4164638b9..e024cd477 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs @@ -49,12 +49,12 @@ internal partial class SimulateCycleSystemGroup : ComponentSystemGroup private readonly List _systemsToUpdate = new List(); - private StaticBroadPhaseSystem _staticBroadPhaseSystem; + //private StaticBroadPhaseSystem _staticBroadPhaseSystem; private DynamicBroadPhaseSystem _dynamicBroadPhaseSystem; - private StaticNarrowPhaseSystem _staticNarrowPhaseSystem; + //private StaticNarrowPhaseSystem _staticNarrowPhaseSystem; private DynamicNarrowPhaseSystem _dynamicNarrowPhaseSystem; - private UpdateDisplacementSystemGroup _displacementSystemGroup; - private StaticCollisionSystem _staticCollisionSystem; + //private UpdateDisplacementSystemGroup _displacementSystemGroup; + //private StaticCollisionSystem _staticCollisionSystem; private DynamicCollisionSystem _dynamicCollisionSystem; //private ContactSystem _contactSystem; //private BallSpinHackPhysics _ballSpinHackPhysics; @@ -134,15 +134,15 @@ private void UpdateCycle() ClearContacts(); _dynamicBroadPhaseSystem.Update(); - _staticBroadPhaseSystem.Update(); - _staticNarrowPhaseSystem.Update(); + // _staticBroadPhaseSystem.Update(); + // _staticNarrowPhaseSystem.Update(); _dynamicNarrowPhaseSystem.Update(); ApplyStaticTime(); - _displacementSystemGroup.Update(); + //_displacementSystemGroup.Update(); _dynamicCollisionSystem.Update(); - _staticCollisionSystem.Update(); + //_staticCollisionSystem.Update(); //_contactSystem.Update(); ClearContacts(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs deleted file mode 100644 index 9fdd1052f..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinballUnity -{ - internal partial class TransformMeshesSystemGroup : ComponentSystemGroup - { - - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs.meta deleted file mode 100644 index 48997e962..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/TransformMeshesSystemGroup.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b3cd4fc2284ab694aba839a05a7a2bc3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs deleted file mode 100644 index 1a8038053..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal partial class UpdateAnimationsSystemGroup : ComponentSystemGroup - { - - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs.meta deleted file mode 100644 index 9a88f51f7..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateAnimationsSystemGroup.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d6d9ca61b61c9d04b857eb9dc132882a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs deleted file mode 100644 index 66dfc7f53..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinball.Unity -{ - [DisableAutoCreation] - internal partial class UpdateDisplacementSystemGroup : ComponentSystemGroup - { - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs.meta deleted file mode 100644 index bbf56bf28..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateDisplacementSystemGroup.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 228103f732034244ca23ad99495adf93 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs deleted file mode 100644 index a04b04866..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal partial class UpdateVelocitiesSystemGroup : ComponentSystemGroup - { - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs.meta deleted file mode 100644 index c28698439..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/UpdateVelocitiesSystemGroup.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0a1634dd6651e6346be17d8fc511f452 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs deleted file mode 100644 index fcb1126f7..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - internal partial class BallDisplacementSystem : SystemBaseStub - { - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("BallDisplacementSystem"); - - protected override void OnCreate() - { - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - } - - protected override void OnUpdate() - { - var dTime = _simulateCycleSystemGroup.HitTime; - var marker = PerfMarker; - - Entities.WithName("BallDisplacementJob").ForEach((ref BallData ball) => { - - if (ball.IsFrozen) { - return; - } - - marker.Begin(); - - ball.Position += ball.Velocity * dTime; - - - //Logger.Debug($"Ball {ball.Id} Position = {ball.Position}"); - - var inertia = ball.Inertia; - var mat3 = CreateSkewSymmetric(ball.AngularMomentum / inertia); - var addedOrientation = math.mul(ball.BallOrientation, mat3); - addedOrientation *= dTime; - - ball.BallOrientation += addedOrientation; - - // do the same for Unity's ball Orientation (where z (and z only rotation) has to be flipped), - // which (maybe??) can't be done after skew matrix operations (or we don't know how)) - // If we flip an exis in the matrix, we always flip two rotations. - var AngMomFlippedZ = new float3(ball.AngularMomentum.x, ball.AngularMomentum.y, -ball.AngularMomentum.z); - mat3 = CreateSkewSymmetric(AngMomFlippedZ / inertia); - addedOrientation = math.mul(ball.BallOrientationForUnity, mat3); - addedOrientation *= dTime; - - ball.BallOrientationForUnity += addedOrientation; - - VPOrthonormalize(ref ball.BallOrientation); - VPOrthonormalize(ref ball.BallOrientationForUnity); - - marker.End(); - - }).Run(); - } - - private static void VPOrthonormalize(ref float3x3 orientation) - { - Vector3 vX = new Vector3(orientation.c0.x, orientation.c1.x, orientation.c2.x); - Vector3 vY = new Vector3(orientation.c0.y, orientation.c1.y, orientation.c2.y); - Vector3 vZ = Vector3.Cross(vX, vY); - vX = Vector3.Normalize(vX); - vZ = Vector3.Normalize(vZ); - vY = Vector3.Cross(vZ, vX); - - orientation.c0.x = vX.x; - orientation.c0.y = vY.x; - orientation.c0.z = vZ.x; - orientation.c1.x = vX.y; - orientation.c1.y = vY.y; - orientation.c1.z = vZ.y; - orientation.c2.x = vX.z; - orientation.c2.y = vY.z; - orientation.c2.z = vZ.z; - - } - - private static float3x3 CreateSkewSymmetric(in float3 pv3D) - { - return new float3x3( - 0, -pv3D.z, pv3D.y, - pv3D.z, 0, -pv3D.x, - -pv3D.y, pv3D.x, 0 - ); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs.meta deleted file mode 100644 index 7c392f41d..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 22ede533e7e963a478cac75e3f0d3404 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index 5618a86a3..8be95caeb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -100,34 +100,34 @@ public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float _player.Balls[kickerId] = ballGo; var world = World.DefaultGameObjectInjectionWorld; - var ecbs = world.GetOrCreateSystemManaged(); - var ecb = ecbs.CreateCommandBuffer(); - - ecb.AddBuffer(entity); - ecb.AddBuffer(entity); - ecb.AddBuffer(entity); - - ecb.AddComponent(entity, new BallData { - Id = id, - IsFrozen = kickerId != 0, - Position = localPos, - Radius = radius, - Mass = mass, - Velocity = localVel, - BallOrientation = float3x3.identity, - BallOrientationForUnity = float3x3.identity, - RingCounterOldPos = 0, - AngularMomentum = float3.zero, - LastPositions = new BallPositions(new float3(float.MaxValue, float.MaxValue, float.MaxValue)) - }); - - ecb.AddComponent(entity, new CollisionEventData { - HitTime = -1, - HitDistance = 0, - HitFlag = false, - IsContact = false, - HitNormal = new float3(0, 0, 0), - }); + // var ecbs = world.GetOrCreateSystemManaged(); + // var ecb = ecbs.CreateCommandBuffer(); + // + // ecb.AddBuffer(entity); + // ecb.AddBuffer(entity); + // ecb.AddBuffer(entity); + // + // ecb.AddComponent(entity, new BallData { + // Id = id, + // IsFrozen = kickerId != 0, + // Position = localPos, + // Radius = radius, + // Mass = mass, + // Velocity = localVel, + // BallOrientation = float3x3.identity, + // BallOrientationForUnity = float3x3.identity, + // RingCounterOldPos = 0, + // AngularMomentum = float3.zero, + // LastPositions = new BallPositions(new float3(float.MaxValue, float.MaxValue, float.MaxValue)) + // }); + // + // ecb.AddComponent(entity, new CollisionEventData { + // HitTime = -1, + // HitDistance = 0, + // HitFlag = false, + // IsContact = false, + // HitNormal = new float3(0, 0, 0), + // }); // // var lastBallPostBuffer = ecb.AddBuffer(entity); // for (var i = 0; i < BallRingCounterPhysics.MaxBallTrailPos; i++) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs deleted file mode 100644 index 082ca0df6..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs +++ /dev/null @@ -1,130 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using Unity.Collections; -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using VisualPinball.Engine.Game; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -using Object = UnityEngine.Object; - -namespace VisualPinballUnity -{ - [AlwaysSynchronizeSystem] - [UpdateInGroup(typeof(UpdateDisplacementSystemGroup))] - [Obsolete("Use FlipperDisplacementPhysics instead.")] - internal partial class FlipperDisplacementSystem : SystemBaseStub - { - private Player _player; - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - private NativeQueue _eventQueue; - - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("FlipperDisplacementSystem"); - - protected override void OnCreate() - { - _player = Object.FindObjectOfType(); - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - _eventQueue = new NativeQueue(Allocator.Persistent); - } - - protected override void OnDestroy() - { - _eventQueue.Dispose(); - } - - protected override void OnUpdate() - { - var dTime = _simulateCycleSystemGroup.HitTime; - var events = _eventQueue.AsParallelWriter(); - var marker = PerfMarker; - var currentTime = SystemAPI.Time.ElapsedTime; - - // fixme job - // Entities.WithName("FlipperDisplacementJob").ForEach((Entity entity, ref FlipperMovementData state, ref FlipperTricksData tricks, in FlipperStaticData data) => { - // - // marker.Begin(); - // - // state.Angle += state.AngleSpeed * dTime; // move flipper angle - // - // var angleMin = math.min(data.AngleStart, tricks.AngleEnd); - // var angleMax = math.max(data.AngleStart, tricks.AngleEnd); - // - // if (state.Angle > angleMax) { - // state.Angle = angleMax; - // } - // - // if (state.Angle < angleMin) { - // state.Angle = angleMin; - // } - // - // if (math.abs(state.AngleSpeed) < 0.0005f) { - // // avoids "jumping balls" when two or more balls held on flipper (and more other balls are in play) //!! make dependent on physics update rate - // marker.End(); - // return; - // } - // - // var handleEvent = false; - // - // if (state.Angle == tricks.AngleEnd) { - // tricks.FlipperAngleEndTime = currentTime; - // } - // - // if (state.Angle >= angleMax) { - // // hit stop? - // if (state.AngleSpeed > 0) { - // handleEvent = true; - // } - // - // } else if (state.Angle <= angleMin) { - // if (state.AngleSpeed < 0) { - // handleEvent = true; - // } - // } - // - // if (handleEvent) { - // var angleSpeed = math.abs(math.degrees(state.AngleSpeed)); - // state.AngularMomentum *= -0.3f; // make configurable? - // state.AngleSpeed = state.AngularMomentum / data.Inertia; - // - // if (state.EnableRotateEvent > 0) { - // - // // send EOS event - // events.Enqueue(new EventData(EventId.LimitEventsEos, entity, angleSpeed)); - // - // } else if (state.EnableRotateEvent < 0) { - // - // // send BOS event - // events.Enqueue(new EventData(EventId.LimitEventsBos, entity, angleSpeed)); - // } - // - // state.EnableRotateEvent = 0; - // } - // - // marker.End(); - // - // }).Run(); - - // dequeue events - while (_eventQueue.TryDequeue(out var eventData)) { - _player.OnEvent(in eventData); - } - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs.meta deleted file mode 100644 index f0206729d..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bc4aedced3dcace46a35c7d3ef279aec -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs deleted file mode 100644 index d7d2761e8..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [AlwaysSynchronizeSystem] - [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class FlipperRotateSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("FlipperRotateSystem"); - - private Player _player; - - protected override void OnStartRunning() - { - base.OnStartRunning(); - _player = Object.FindObjectOfType(); - } - - protected override void OnUpdate() - { - // fixme job - // var marker = PerfMarker; - // Entities.WithoutBurst().WithName("FlipperRotateJob").ForEach((Entity entity, in FlipperMovementData movement) => { - // - // marker.Begin(); - // - // _player.FlipperTransforms[entity].localRotation = quaternion.Euler(0, movement.Angle, 0); - // - // marker.End(); - // - // }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs.meta deleted file mode 100644 index 4d0846eb6..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperRotateSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 430201287c4577648af97349897ff952 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs deleted file mode 100644 index 20bb5de74..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs +++ /dev/null @@ -1,192 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable CompareOfFloatsByEqualityOperator - -using System; -using Unity.Entities; -using Unity.Mathematics; -using Unity.Profiling; -using VisualPinball.Engine.Common; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [AlwaysSynchronizeSystem] - [UpdateInGroup(typeof(UpdateVelocitiesSystemGroup))] - [Obsolete("Use FlipperVelocityPhysics instead.")] - internal partial class FlipperVelocitySystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("FlipperVelocitySystem"); - - protected override void OnUpdate() - { - var marker = PerfMarker; - Entities.WithName("FlipperVelocityJob").ForEach((ref FlipperMovementData mState, ref FlipperVelocityData vState, ref FlipperTricksData tricks, in SolenoidStateData solenoid, in FlipperStaticData data) => - { - - marker.Begin(); - - var angleMin = math.min(data.AngleStart, tricks.AngleEnd); - var angleMax = math.max(data.AngleStart, tricks.AngleEnd); - var minIsStart = angleMin == data.AngleStart; // Usually true for the right Flipper - - var desiredTorque = data.Strength; - if (!solenoid.Value) - { - // True solState = button pressed, false = released - desiredTorque *= -data.ReturnRatio; - } - - if (tricks.UseFlipperTricksPhysics) { - // check if solenoid was just activated or deactivated - if (solenoid.Value != tricks.lastSolState) - { - // check if solenoid was just activated or deactivated for Flippertricks - // Flippertricks case 1 and 2 are always before case 3, 4 and 5. - if (solenoid.Value) - { - // Flippertricks, case 2 (OnButtonActivate) - tricks.TorqueDamping = tricks.OriginalTorqueDamping; - tricks.TorqueDampingAngle = tricks.OriginalTorqueDampingAngle; - tricks.ElasticityMultiplier = 1f; - } - else - { - // Flippertricks, case 1 (OnButtonDeactivate) - tricks.TorqueDamping = tricks.OriginalTorqueDamping * tricks.EOSReturn / data.ReturnRatio; - tricks.TorqueDampingAngle = tricks.OriginalTorqueDampingAngle; - } - } - } - - // hold coil is weaker - float eosAngle = math.radians(tricks.TorqueDampingAngle); - if (math.abs(mState.Angle - tricks.AngleEnd) < eosAngle) { - // fade in/out damping, depending on angle to end - var lerp = math.pow(math.abs(mState.Angle - tricks.AngleEnd) / eosAngle, 4); - if (tricks.UseFlipperTricksPhysics) - desiredTorque *= lerp + tricks.TorqueDamping * (1 - lerp); - else - desiredTorque *= lerp + tricks.TorqueDamping * (1 - lerp); - } - - if (!vState.Direction) { - desiredTorque = -desiredTorque; - } - - var torqueRampUpSpeed = tricks.RampUpSpeed; - if (torqueRampUpSpeed <= 0) { - // set very high for instant coil response - torqueRampUpSpeed = 1e6f; - - } else { - torqueRampUpSpeed = math.min(data.Strength / torqueRampUpSpeed, 1e6f); - } - - // update current torque linearly towards desired torque - // (simple model for coil hysteresis) - if (desiredTorque >= vState.CurrentTorque) { - vState.CurrentTorque = math.min(vState.CurrentTorque + torqueRampUpSpeed * (float)PhysicsConstants.PhysFactor, desiredTorque); - - } else { - vState.CurrentTorque = math.max(vState.CurrentTorque - torqueRampUpSpeed * (float)PhysicsConstants.PhysFactor, desiredTorque); - } - - // resolve contacts with stoppers - var torque = vState.CurrentTorque; - vState.IsInContact = false; - if (math.abs(mState.AngleSpeed) <= 1e-2) { - - if (mState.Angle >= angleMax - 1e-2 && torque > 0) { - mState.Angle = angleMax; - vState.IsInContact = true; - vState.ContactTorque = torque; - mState.AngularMomentum = 0f; - torque = 0f; - - } else if (mState.Angle <= angleMin + 1e-2 && torque < 0) { - mState.Angle = angleMin; - vState.IsInContact = true; - vState.ContactTorque = torque; - mState.AngularMomentum = 0f; - torque = 0f; - } - } - - mState.AngularMomentum += (float)PhysicsConstants.PhysFactor * torque; - mState.AngleSpeed = mState.AngularMomentum / data.Inertia; - vState.AngularAcceleration = torque / data.Inertia; - - if (tricks.UseFlipperTricksPhysics) - { - // Flippertricks, case 3 (OnFlipperDown) and 4 (OnFlipperUpResting) - if (!tricks.WasInContact && vState.IsInContact) - { - // the flipper stopped due to being at max or min angle. - // so check if at start angle - if (((mState.Angle == angleMin) && (minIsStart)) || - ((mState.Angle == angleMax) && (!minIsStart))) - { - // is at start angle - // FlipperTricks case 3: OnFlipperDown - if (minIsStart) - tricks.AngleEnd = tricks.OriginalAngleEnd + tricks.Overshoot; - else - tricks.AngleEnd = tricks.OriginalAngleEnd - tricks.Overshoot; - - tricks.RampUpSpeed = tricks.SOSRampUp; - tricks.ElasticityMultiplier = tricks.SOSEM; - - //data.ft = 3f; - } - else - { - // is at end angle - // FlipperTricks case 4: OnFlipperUpResting - tricks.AngleEnd = tricks.OriginalAngleEnd; // This causes the flipper to instantly flip back to normal end angle (like in the original Flippertricks implementation) - tricks.RampUpSpeed = tricks.EOSRampup; - tricks.TorqueDamping = tricks.EOSTNew; - tricks.TorqueDampingAngle = tricks.EOSANew; - - //data.ft = 4f; - } - } - - // Flippertricks, case 5 (OnEnterinbetween) (and pressed) - if ((tricks.WasInContact) && (!vState.IsInContact) && solenoid.Value) - { - // Flippertricks Case 5 - tricks.RampUpSpeed = tricks.OriginalRampUpSpeed; - tricks.TorqueDamping = tricks.OriginalTorqueDamping; - tricks.TorqueDampingAngle = tricks.OriginalTorqueDampingAngle; - tricks.ElasticityMultiplier = 1f; - - //data.ft = 5f; - } - - tricks.WasInContact = vState.IsInContact; - - // check if solenoid was just activated or deactivated - tricks.lastSolState = solenoid.Value; - } - marker.End(); - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs.meta deleted file mode 100644 index 7e1ef90d3..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocitySystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5d22edc5cea271f4b9b58aa9af85efb8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs new file mode 100644 index 000000000..10e0db32b --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs @@ -0,0 +1,76 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Engine.Game; +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class DropTargetAnimation + { + internal static void Update(int itemId, ref DropTargetAnimationData data, in DropTargetStaticData staticData, + ref PhysicsState state, uint timeMsec) + { + var oldTimeMsec = data.TimeMsec < timeMsec ? data.TimeMsec : timeMsec; + data.TimeMsec = timeMsec; + var diffTimeMsec = (float)(timeMsec - oldTimeMsec); + + if (data.HitEvent) { + if (!data.IsDropped) { + data.MoveDown = true; + } + + data.MoveAnimation = true; + data.HitEvent = false; + } + + if (data.MoveAnimation) { + var step = staticData.Speed; + + if (data.MoveDown) { + step = -step; + + } else if (data.TimeMsec - data.TimeStamp < (uint) staticData.RaiseDelay) { + step = 0.0f; + } + + data.ZOffset += step * diffTimeMsec; + if (data.MoveDown) { + if (data.ZOffset <= -DropTargetAnimationData.DropTargetLimit) { + data.ZOffset = -DropTargetAnimationData.DropTargetLimit; + data.MoveDown = false; + data.IsDropped = true; + data.MoveAnimation = false; + data.TimeStamp = 0; + if (staticData.UseHitEvent) { + state.EventQueue.Enqueue(new EventData(EventId.TargetEventsDropped, itemId)); + } + } + + } else { + if (data.ZOffset >= 0.0f) { + data.ZOffset = 0.0f; + data.MoveAnimation = false; + data.IsDropped = false; + if (staticData.UseHitEvent) { + state.EventQueue.Enqueue(new EventData(EventId.TargetEventsRaised, itemId)); + } + } + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs deleted file mode 100644 index c4f8adbe8..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationSystem.cs +++ /dev/null @@ -1,119 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Collections; -using Unity.Entities; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Engine.Game; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class DropTargetAnimationSystem : SystemBaseStub - { - private Player _player; - private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; - private NativeQueue _eventQueue; - - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("HitTargetAnimationSystem"); - - protected override void OnCreate() - { - _player = Object.FindObjectOfType(); - _visualPinballSimulationSystemGroup = World.GetOrCreateSystemManaged(); - _eventQueue = new NativeQueue(Allocator.Persistent); - } - - protected override void OnDestroy() - { - _eventQueue.Dispose(); - } - - protected override void OnUpdate() - { - var timeMsec = _visualPinballSimulationSystemGroup.TimeMsec; - var events = _eventQueue.AsParallelWriter(); - var marker = PerfMarker; - - // fixme job - // Entities - // .WithName("HitTargetAnimationJob") - // .ForEach((Entity entity, ref DropTargetAnimationData data, in DropTargetStaticData staticData) => - // { - // marker.Begin(); - // - // var oldTimeMsec = data.TimeMsec < timeMsec ? data.TimeMsec : timeMsec; - // data.TimeMsec = timeMsec; - // var diffTimeMsec = (float)(timeMsec - oldTimeMsec); - // - // if (data.HitEvent) { - // if (!data.IsDropped) { - // data.MoveDown = true; - // } - // - // data.MoveAnimation = true; - // data.HitEvent = false; - // } - // - // if (data.MoveAnimation) { - // var step = staticData.Speed; - // - // if (data.MoveDown) { - // step = -step; - // - // } else if (data.TimeMsec - data.TimeStamp < (uint) staticData.RaiseDelay) { - // step = 0.0f; - // } - // - // data.ZOffset += step * diffTimeMsec; - // if (data.MoveDown) { - // if (data.ZOffset <= -DropTargetAnimationData.DropTargetLimit) { - // data.ZOffset = -DropTargetAnimationData.DropTargetLimit; - // data.MoveDown = false; - // data.IsDropped = true; - // data.MoveAnimation = false; - // data.TimeStamp = 0; - // if (staticData.UseHitEvent) { - // events.Enqueue(new EventData(EventId.TargetEventsDropped, entity)); - // } - // } - // - // } else { - // if (data.ZOffset >= 0.0f) { - // data.ZOffset = 0.0f; - // data.MoveAnimation = false; - // data.IsDropped = false; - // if (staticData.UseHitEvent) { - // events.Enqueue(new EventData(EventId.TargetEventsRaised, entity)); - // } - // } - // } - // } - // - // marker.End(); - // - // }).Run(); - - // dequeue events - while (_eventQueue.TryDequeue(out var eventData)) { - _player.OnEvent(in eventData); - } - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs deleted file mode 100644 index e07ff5d81..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; -using Physics = UnityEngine.Physics; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class DropTargetTransformationSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker(nameof(DropTargetTransformationSystem)); - private Player _player; - - protected override void OnStartRunning() - { - base.OnStartRunning(); - _player = Object.FindObjectOfType(); - } - - protected override void OnUpdate() - { - // fixme job - // var marker = PerfMarker; - // Entities.WithoutBurst().WithName("DropTargetTransformationJob").ForEach((Entity entity, in DropTargetAnimationData data) => - // { - // marker.Begin(); - // - // var localPos = _player.DropTargetTransforms[entity].localPosition; - // _player.DropTargetTransforms[entity].localPosition = new Vector3( - // localPos.x, - // VisualPinball.Unity.Physics.ScaleToWorld(data.ZOffset), - // localPos.z - // ); - // - // marker.End(); - // - // }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs.meta deleted file mode 100644 index 54b09480c..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetTransformationSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4a74e339b9e173d468ec0e0bd1d7401c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimation.cs new file mode 100644 index 000000000..621028cb4 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimation.cs @@ -0,0 +1,58 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using VisualPinball.Unity; + +namespace VisualPinballUnity +{ + internal static class HitTargetAnimation + { + internal static void Update(ref HitTargetAnimationData data, in HitTargetStaticData staticData, + uint timeMsec) + { + var oldTimeMsec = data.TimeMsec < timeMsec ? data.TimeMsec : timeMsec; + data.TimeMsec = timeMsec; + var diffTimeMsec = (float)(timeMsec - oldTimeMsec); + + if (data.HitEvent) { + data.MoveAnimation = true; + data.HitEvent = false; + } + + if (data.MoveAnimation) { + var step = staticData.Speed; + if (!data.MoveDirection) { + step = -step; + } + + data.XRotation += step * diffTimeMsec; + if (data.MoveDirection) { + if (data.XRotation >= staticData.MaxAngle) { + data.XRotation = staticData.MaxAngle; + data.MoveDirection = false; + } + + } else { + if (data.XRotation <= 0.0f) { + data.XRotation = 0.0f; + data.MoveAnimation = false; + data.MoveDirection = true; + } + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimation.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimation.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs deleted file mode 100644 index fca5b0d35..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimationSystem.cs +++ /dev/null @@ -1,91 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Collections; -using Unity.Entities; -using Unity.Profiling; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(UpdateAnimationsSystemGroup))] - internal partial class HitTargetAnimationSystem : SystemBaseStub - { - private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; - private NativeQueue _eventQueue; - - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker(nameof(HitTargetAnimationSystem)); - - protected override void OnCreate() - { - _visualPinballSimulationSystemGroup = World.GetOrCreateSystemManaged(); - _eventQueue = new NativeQueue(Allocator.Persistent); - } - - protected override void OnDestroy() - { - _eventQueue.Dispose(); - } - - protected override void OnUpdate() - { - var timeMsec = _visualPinballSimulationSystemGroup.TimeMsec; - var marker = PerfMarker; - - Entities - .WithName("HitTargetAnimationJob") - .ForEach((Entity entity, ref HitTargetAnimationData data, in HitTargetStaticData staticData) => - { - marker.Begin(); - - var oldTimeMsec = data.TimeMsec < timeMsec ? data.TimeMsec : timeMsec; - data.TimeMsec = timeMsec; - var diffTimeMsec = (float)(timeMsec - oldTimeMsec); - - if (data.HitEvent) { - data.MoveAnimation = true; - data.HitEvent = false; - } - - if (data.MoveAnimation) { - var step = staticData.Speed; - if (!data.MoveDirection) { - step = -step; - } - - data.XRotation += step * diffTimeMsec; - if (data.MoveDirection) { - if (data.XRotation >= staticData.MaxAngle) { - data.XRotation = staticData.MaxAngle; - data.MoveDirection = false; - } - - } else { - if (data.XRotation <= 0.0f) { - data.XRotation = 0.0f; - data.MoveAnimation = false; - data.MoveDirection = true; - } - } - } - - marker.End(); - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs deleted file mode 100644 index 26313e7e6..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Profiling; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [UpdateInGroup(typeof(TransformMeshesSystemGroup))] - internal partial class HitTargetTransformationSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker(nameof(HitTargetTransformationSystem)); - private Player _player; - - protected override void OnStartRunning() - { - base.OnStartRunning(); - _player = Object.FindObjectOfType(); - } - - protected override void OnUpdate() - { - // fixme job - // var marker = PerfMarker; - // Entities.WithoutBurst().WithName("HitTargetTransformationJob").ForEach((Entity entity, - // in HitTargetAnimationData data, in HitTargetStaticData staticData) => - // { - // marker.Begin(); - // - // var localRot = _player.HitTargetTransforms[entity].transform.localEulerAngles; - // _player.HitTargetTransforms[entity].transform.localEulerAngles = new Vector3( - // data.XRotation, - // localRot.y, - // localRot.z - // ); - // - // marker.End(); - // - // }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs.meta deleted file mode 100644 index eeec43b97..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetTransformationSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4c4dddeb8a2b43243a7b6af2941accdd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From aa01ad8ea92d8062de239df580ac4fd6c5d7044c Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 10 Oct 2023 23:26:42 +0200 Subject: [PATCH 080/159] jobs: Port flipper correction code. Still not triggering though. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 3 + .../Game/PhysicsStaticCollision.cs | 85 +++++++-------- .../VPT/Flipper/FlipperComponent.cs | 102 ++++++++++++++++-- .../VPT/Flipper/FlipperCorrectionBlob.cs | 2 +- .../VPT/Flipper/FlipperCorrectionData.cs | 1 + .../VPT/Trigger/TriggerCollider.cs | 1 + .../VPT/Trigger/TriggerColliderComponent.cs | 13 +++ .../VPT/Trigger/TriggerComponent.cs | 48 ++++++++- .../VPT/Trigger/TriggerState.cs | 18 ++++ 9 files changed, 211 insertions(+), 62 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index c1af9877e..67f7dadbb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -289,6 +289,9 @@ private void Update() using (var enumerator = _triggerStates.GetEnumerator()) { while (enumerator.MoveNext()) { ref var triggerState = ref enumerator.Current.Value; + if (triggerState.AnimatedItemId == 0) { + continue; + } var triggerTransform = _transforms[triggerState.AnimatedItemId]; TriggerTransform.Update(triggerState.AnimatedItemId, in triggerState.Movement, triggerTransform); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 9c61be936..7f4229706 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -40,34 +40,40 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta { var colliderId = ball.CollisionEvent.ColliderId; var collider = state.GetCollider(colliderId); - if (CollidesWithItem(ref collider, ref ball, ref state)) { + if (CollidesWithItem(ref collider, ref ball, ref state, timeMs)) { return; } switch (state.Colliders.GetType(colliderId)) { case ColliderType.Circle: - state.Colliders.GetCircleCollider(colliderId).Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); + ref var circleCollider = ref state.Colliders.GetCircleCollider(colliderId); + circleCollider.Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Plane: - state.Colliders.GetPlaneCollider(colliderId).Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); + ref var planeCollider = ref state.Colliders.GetPlaneCollider(colliderId); + planeCollider.Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Line: - state.Colliders.GetLineCollider(colliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + ref var lineCollider = ref state.Colliders.GetLineCollider(colliderId); + lineCollider.Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Triangle: - state.Colliders.GetTriangleCollider(colliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + ref var triangleCollider = ref state.Colliders.GetTriangleCollider(colliderId); + triangleCollider.Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Line3D: - state.Colliders.GetLine3DCollider(colliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + ref var line3DCollider = ref state.Colliders.GetLine3DCollider(colliderId); + line3DCollider.Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Point: - state.Colliders.GetPointCollider(colliderId).Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + ref var pointCollider = ref state.Colliders.GetPointCollider(colliderId); + pointCollider.Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Bumper: @@ -78,9 +84,11 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta case ColliderType.Flipper: ref var flipperState = ref state.GetFlipperState(colliderId); - state.Colliders.GetFlipperCollider(colliderId).Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, + ref var flipperCollider = ref state.Colliders.GetFlipperCollider(colliderId); + flipperCollider.Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, ref state.EventQueue, in ball.Id, in flipperState.Tricks, in flipperState.Static, - in flipperState.Velocity, in flipperState.Hit, timeMs); + in flipperState.Velocity, in flipperState.Hit, timeMs + ); break; case ColliderType.Gate: @@ -91,7 +99,8 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta case ColliderType.LineSlingShot: ref var surfaceState = ref state.GetSurfaceState(colliderId); - state.Colliders.GetLineSlingshotCollider(colliderId).Collide(ref ball, ref state.EventQueue, in surfaceState.Slingshot, + ref var surfaceCollider = ref state.Colliders.GetLineSlingshotCollider(colliderId); + surfaceCollider.Collide(ref ball, ref state.EventQueue, in surfaceState.Slingshot, in ball.CollisionEvent, ref state.Env.Random); break; @@ -107,24 +116,7 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta case ColliderType.TriggerCircle: case ColliderType.TriggerLine: - ref var triggerState = ref state.GetTriggerState(colliderId); - TriggerCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref state.InsideOfs, ref triggerState.Animation, in collider); - - // if (HasComponent(coll.ItemId)) { - // if (triggerAnimationData.UnHitEvent) { - // var flipperCorrectionData = GetComponent(coll.ItemId); - // ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; - // var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // var flipperTricksData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // FlipperCorrection.OnBallLeaveFlipper( - // ref ballData, ref flipperCorrectionBlob, in flipperMovementData, in flipperTricksData, in flipperStaticData, timeMsec - // ); - // } - // - // } else { - // SetComponent(coll.ItemId, triggerAnimationData); - // } + TriggerCollide(ref ball, ref state, in collider, timeMs); break; case ColliderType.KickerCircle: @@ -135,7 +127,7 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta } } - private static bool CollidesWithItem(ref Collider collider, ref BallData ball, ref PhysicsState state) + private static bool CollidesWithItem(ref Collider collider, ref BallData ball, ref PhysicsState state, uint timeMs) { // hit target var colliderId = ball.CollisionEvent.ColliderId; @@ -159,30 +151,25 @@ private static bool CollidesWithItem(ref Collider collider, ref BallData ball, r // trigger } else if (collider.Header.ItemType == ItemType.Trigger) { - - ref var triggerState = ref state.GetTriggerState(colliderId); - TriggerCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref state.InsideOfs, ref triggerState.Animation, in collider); + TriggerCollide(ref ball, ref state, in collider, timeMs); return true; - - // if (HasComponent(collider.ItemId)) { - // if (triggerAnimationData.UnHitEvent) { - // var flipperCorrectionData = GetComponent(collider.ItemId); - // ref var flipperCorrectionBlob = ref flipperCorrectionData.Value.Value; - // var flipperMovementData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // var flipperStaticData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // var flipperTricksData = GetComponent(flipperCorrectionBlob.FlipperEntity); - // FlipperCorrection.OnBallLeaveFlipper( - // ref ballData, ref flipperCorrectionBlob, in flipperMovementData, in flipperTricksData, in flipperStaticData, timeMsec - // ); - // } - // - // } else { - // SetComponent(collider.ItemId, triggerAnimationData); - // } - } return false; } + + private static void TriggerCollide(ref BallData ball, ref PhysicsState state, in Collider collider, uint timeMs) + { + ref var triggerState = ref state.GetTriggerState(collider.Id); + TriggerCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref state.InsideOfs, ref triggerState.Animation, in collider); + + if (triggerState.FlipperCorrection.IsEnabled) { + if (triggerState.Animation.UnHitEvent) { + ref var flipperCorrectionBlob = ref triggerState.FlipperCorrection.Value.Value; + ref var fs = ref state.GetFlipperState(flipperCorrectionBlob.FlipperItemId); + FlipperCorrection.OnBallLeaveFlipper(ref ball, ref flipperCorrectionBlob, in fs.Movement, in fs.Tricks, in fs.Static, timeMs); + } + } + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index d9feab46c..4c9651af0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -24,11 +24,14 @@ using System; using System.Collections.Generic; using Unity.Mathematics; +using UnityEditor; using UnityEngine; using VisualPinball.Engine.Game.Engines; +using VisualPinball.Engine.Math; using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.Flipper; using VisualPinball.Engine.VPT.Table; +using Color = UnityEngine.Color; namespace VisualPinball.Unity { @@ -356,7 +359,7 @@ protected void OnDrawGizmosSelected() } Gizmos.matrix = Matrix4x4.identity; - UnityEditor.Handles.matrix = Matrix4x4.identity; + Handles.matrix = Matrix4x4.identity; // Draw enclosing polygon Gizmos.color = Color.cyan; @@ -487,17 +490,16 @@ private void Start() #endregion - #region DOTS Data + #region State internal FlipperState CreateState() { var colliderComponent = gameObject.GetComponent(); - // collision if (colliderComponent) { // vpx physics var d = GetMaterialData(colliderComponent); - return new FlipperState( + var state = new FlipperState( gameObject.GetInstanceID(), d, GetMovementData(d), @@ -508,9 +510,11 @@ internal FlipperState CreateState() ); // flipper correction (nFozzy) - // if (colliderComponent.FlipperCorrection) { - // SetupFlipperCorrection(entity, dstManager, player, colliderComponent); - // } + if (colliderComponent.FlipperCorrection) { + SetupFlipperCorrection(colliderComponent); + } + + return state; } return default; } @@ -632,6 +636,90 @@ internal FlipperHitData GetHitData() }; } + private void SetupFlipperCorrection(FlipperColliderComponent colliderComponent) + { + var fc = colliderComponent.FlipperCorrection; + var ta = GetComponentInParent(); + + if (!ta) { + throw new InvalidOperationException("Cannot create correction trigger for flipper outside of the table hierarchy."); + } + + // create new gameobject with the correct components, the gameobject will handle itself after that. + var go = new GameObject { + name = $"{name} (Flipper Correction)", + }; + go.transform.SetParent(gameObject.transform.parent, false); + var triggerComponent = go.AddComponent(); + var triggerCollider = go.AddComponent(); + + triggerCollider.ForFlipper = this; + triggerCollider.TimeThresholdMs = fc.TimeThresholdMs; + + var localPos = transform.localPosition.TranslateToVpx(); + triggerComponent.Position = new Vector2(localPos.x, localPos.y); + + var poly = GetEnclosingPolygon(23, 12); + triggerComponent.DragPoints = new DragPointData[poly.Count]; + triggerComponent.IsLocked = true; + triggerCollider.HitHeight = 150F; // nFozzy's recommendation, but I think 50 should be ok + var flipperRotation = Matrix4x4.Rotate(quaternion.Euler(new float3(0, 0, -_startAngle))); + + for (var i = 0; i < poly.Count; i++) { + // Poly points are expressed in flipper's frame: rotate to get it to the correct position. + var p = flipperRotation.MultiplyPoint(poly[i]); + triggerComponent.DragPoints[poly.Count - i - 1] = new DragPointData(localPos.x - p.x, localPos.y - p.y); + } + + // create polarities and velocities curves + var polarities = new float2[fc.PolaritiesCurveSlicingCount + 1]; + if (fc.Polarities != null) + { + var curve = fc.Polarities; + float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.PolaritiesCurveSlicingCount; + int i = 0; + for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) + { + polarities[i].x = t; + polarities[i++].y = curve.Evaluate(t); + } + } + else + { + for (int i = 0; i < fc.PolaritiesCurveSlicingCount + 1; i++) + { + polarities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; + polarities[i].y = 0F; + } + } + triggerCollider.FlipperPolarities = polarities; + + var velocities = new float2[fc.VelocitiesCurveSlicingCount + 1]; + if (fc.Velocities != null) + { + var curve = fc.Velocities; + float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.VelocitiesCurveSlicingCount; + int i = 0; + for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) + { + velocities[i].x = t; + velocities[i++].y = curve.Evaluate(t); + } + } + else + { + for (int i = 0; i < fc.VelocitiesCurveSlicingCount + 1; i++) + { + velocities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; + velocities[i].y = 1F; + } + } + triggerCollider.FlipperVelocities = velocities; + + // need to explicitly register, since awake was called before the components were added. + GetComponentInParent().Register(triggerComponent); + } + #endregion } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs index 5801067b4..b902934be 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { public struct FlipperCorrectionBlob { - public Entity FlipperEntity; + public int FlipperItemId; public BlobArray Polarities; public BlobArray Velocities; public uint TimeDelayMs; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionData.cs index aae7c2520..f68bf3399 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionData.cs @@ -20,6 +20,7 @@ namespace VisualPinball.Unity { public struct FlipperCorrectionData : IComponentData { + public bool IsEnabled; public BlobAssetReference Value; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs index 0cc33acf4..662b1304b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using Unity.Collections; +using UnityEngine; using VisualPinball.Engine.Common; using VisualPinball.Engine.Game; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs index 26e9f2f73..36afaf9e5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs @@ -18,6 +18,7 @@ using System; using Unity.Entities; +using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.VPT.Trigger; @@ -36,6 +37,18 @@ public class TriggerColliderComponent : ColliderComponent GetPhysicsMaterialData(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs index 6e396e133..54e59b08c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs @@ -24,6 +24,8 @@ using System; using System.Collections.Generic; using System.Linq; +using Unity.Collections; +using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Game.Engines; @@ -253,17 +255,53 @@ internal TriggerState CreateState() var collComponent = GetComponentInChildren(); var animComponent = GetComponentInChildren(); var meshComponent = GetComponentInChildren(); + + if (collComponent.ForFlipper == null) { + return new TriggerState( + gameObject.GetInstanceID(), + animComponent ? animComponent.gameObject.GetInstanceID() : 0, + new TriggerStaticData { + AnimSpeed = animComponent.AnimSpeed, + Radius = collComponent.HitCircleRadius, + Shape = meshComponent.Shape, + TableScaleZ = 1f + }, + new TriggerMovementData(), + new TriggerAnimationData() + ); + } + + // flipper correction trigger has additional data + using var builder = new BlobBuilder(Allocator.Temp); + ref var root = ref builder.ConstructRoot(); + + root.FlipperItemId = collComponent.ForFlipper.gameObject.GetInstanceID(); + root.TimeDelayMs = collComponent.TimeThresholdMs; + + var polarities = builder.Allocate(ref root.Polarities, collComponent.FlipperPolarities.Length); + for (var i = 0; i < collComponent.FlipperPolarities.Length; i++) { + polarities[i] = collComponent.FlipperPolarities[i]; + } + + var velocities = builder.Allocate(ref root.Velocities, collComponent.FlipperVelocities.Length); + for (var i = 0; i < collComponent.FlipperVelocities.Length; i++) { + velocities[i] = collComponent.FlipperVelocities[i]; + } + + var blobAssetRef = builder.CreateBlobAssetReference(Allocator.Persistent); + return new TriggerState( gameObject.GetInstanceID(), - animComponent ? animComponent.gameObject.GetInstanceID() : 0, new TriggerStaticData { - AnimSpeed = animComponent.AnimSpeed, + AnimSpeed = 0, Radius = collComponent.HitCircleRadius, - Shape = meshComponent.Shape, + Shape = TriggerShape.TriggerNone, TableScaleZ = 1f }, - new TriggerMovementData(), - new TriggerAnimationData() + new FlipperCorrectionData { + IsEnabled = true, + Value = blobAssetRef + } ); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs index fd1a93c9f..1e8e9781f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs @@ -23,7 +23,11 @@ internal struct TriggerState internal TriggerStaticData Static; internal TriggerMovementData Movement; internal TriggerAnimationData Animation; + internal FlipperCorrectionData FlipperCorrection; + /// + /// Default trigger usage. + /// public TriggerState(int itemId, int animatedItemId, TriggerStaticData @static, TriggerMovementData movement, TriggerAnimationData animation) { ItemId = itemId; @@ -31,6 +35,20 @@ public TriggerState(int itemId, int animatedItemId, TriggerStaticData @static, T Static = @static; Movement = movement; Animation = animation; + FlipperCorrection = default; + } + + /// + /// Flipper correction usage. + /// + public TriggerState(int itemId, TriggerStaticData @static, FlipperCorrectionData flipperCorrection) + { + ItemId = itemId; + AnimatedItemId = 0; + Static = @static; + Movement = default; + Animation = default; + FlipperCorrection = flipperCorrection; } } } From d11544681a48d9ba8aab34fb08edba86fc93aed4 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 11 Oct 2023 23:31:11 +0200 Subject: [PATCH 081/159] jobs: Fix flipper correction collider. --- .../VisualPinball.Unity/Physics/Collision/ColliderBlob.cs | 2 -- .../VisualPinball.Unity/VPT/Table/SceneTableContainer.cs | 4 ++++ .../VisualPinball.Unity/VPT/Trigger/TriggerApi.cs | 6 ++---- .../VPT/Trigger/TriggerColliderGenerator.cs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs index 66a0e3efd..fa96808cb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs @@ -21,7 +21,5 @@ namespace VisualPinball.Unity internal struct ColliderBlob : IComponentData { public BlobArray> Colliders; - public int PlayfieldColliderId; - public int GlassColliderId; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Table/SceneTableContainer.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Table/SceneTableContainer.cs index aa646d576..2e40a2668 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Table/SceneTableContainer.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Table/SceneTableContainer.cs @@ -104,6 +104,10 @@ public void Refresh(bool forExport = false) { var stopWatch = Stopwatch.StartNew(); Clear(); + if (!_tableComponent.LegacyContainer) { + _tableComponent.LegacyContainer = ScriptableObject.CreateInstance(); + _tableComponent.LegacyContainer.TableData = new TableData(); + } WalkChildren(_tableComponent.transform, node => RefreshChild(node, forExport)); _tableComponent.CopyDataTo(_tableComponent.LegacyContainer.TableData, MaterialNames, TextureNames, forExport); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs index 8f61dc3bb..524d61fcd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs @@ -67,10 +67,8 @@ internal TriggerApi(GameObject go, Player player) protected override void CreateColliders(ref ColliderReference colliders, float margin) { var meshComponent = GameObject.GetComponent(); - if (meshComponent) { - var colliderGenerator = new TriggerColliderGenerator(this, MainComponent, ColliderComponent, meshComponent); - colliderGenerator.GenerateColliders(ref colliders); - } + var colliderGenerator = new TriggerColliderGenerator(this, MainComponent, ColliderComponent, meshComponent); + colliderGenerator.GenerateColliders(ref colliders); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderGenerator.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderGenerator.cs index 5aaa7abe2..2bda3eeb8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderGenerator.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderGenerator.cs @@ -29,7 +29,7 @@ public class TriggerColliderGenerator private readonly TriggerMeshComponent _meshComponent; private readonly TriggerColliderComponent _colliderComponent; - private bool IsRound => _meshComponent.Shape == TriggerShape.TriggerStar || _meshComponent.Shape == TriggerShape.TriggerButton; + private bool IsRound => _meshComponent && _meshComponent.Shape is TriggerShape.TriggerStar or TriggerShape.TriggerButton; public TriggerColliderGenerator(TriggerApi triggerApi, TriggerComponent component, TriggerColliderComponent colliderComponent, TriggerMeshComponent meshComponent) { From c690b43030036448280cac3358ff46785f953719 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 12 Oct 2023 23:20:45 +0200 Subject: [PATCH 082/159] jobs: Fix ball creation through ball manager. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 79 ++++++---- .../VisualPinball.Unity/Game/Player.cs | 19 +-- .../Physics/Engine/DefaultPhysicsEngine.cs | 12 +- .../Physics/Engine/IPhysicsEngine.cs | 5 +- .../Ball/BallComponent.cs} | 100 ++++++------ .../Ball/BallComponent.cs.meta} | 4 +- .../VPT/Ball/BallDisplacementPhysics.cs | 4 + .../VPT/Ball/BallManager.cs | 143 +++--------------- 8 files changed, 140 insertions(+), 226 deletions(-) rename VisualPinball.Unity/VisualPinball.Unity/{Game/PhysicsBall.cs => VPT/Ball/BallComponent.cs} (78%) rename VisualPinball.Unity/VisualPinball.Unity/{Game/PhysicsBall.cs.meta => VPT/Ball/BallComponent.cs.meta} (97%) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 67f7dadbb..80d3e9b3b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -24,6 +24,7 @@ using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Common; +using VisualPinball.Unity.Collections; using VisualPinballUnity; using Debug = UnityEngine.Debug; @@ -31,14 +32,15 @@ namespace VisualPinball.Unity { public class PhysicsEngine : MonoBehaviour { - internal delegate void InputAction(ref PhysicsState state); + #region States + [NonSerialized] private InsideOfs _insideOfs; [NonSerialized] private NativeArray _physicsEnv; [NonSerialized] private NativeOctree _octree; - [NonSerialized] private BlobAssetReference _colliders; [NonSerialized] private NativeQueue _eventQueue; - [NonSerialized] private InsideOfs _insideOfs; - [NonSerialized] private NativeParallelHashMap _balls; + [NonSerialized] private BlobAssetReference _colliders; + + [NonSerialized] private NativeParallelHashMap _ballStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _bumperStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _flipperStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _gateStates = new(0, Allocator.Persistent); @@ -50,16 +52,29 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeParallelHashMap _surfaceStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _triggerStates = new(0, Allocator.Persistent); - [NonSerialized] private readonly Dictionary _ballLookup = new(); + #endregion + + #region Transforms + [NonSerialized] private readonly Dictionary _transforms = new(); [NonSerialized] private readonly Dictionary _skinnedMeshRenderers = new(); + #endregion + [NonSerialized] private readonly Queue _inputActions = new(); [NonSerialized] private Player _player; private static ulong NowUsec => (ulong)(Time.timeAsDouble * 1000000); + #region API + + internal delegate void InputAction(ref PhysicsState state); + + internal void Schedule(InputAction action) => _inputActions.Enqueue(action); + internal ref KickerState KickerState(int itemId) => ref _kickerStates.GetValueByRef(itemId); + internal void SetBallInsideOf(int ballId, int itemId) => _insideOfs.SetInsideOf(itemId, ballId); + internal void Register(T item) where T : MonoBehaviour { var go = item.gameObject; @@ -67,6 +82,11 @@ internal void Register(T item) where T : MonoBehaviour _transforms.TryAdd(itemId, go.transform); switch (item) { + case BallComponent c: + if (!_ballStates.ContainsKey(itemId)) { + _ballStates[itemId] = c.CreateState(); + } + break; case BumperComponent c: _bumperStates[itemId] = c.CreateState(); break; case FlipperComponent c: _flipperStates[itemId] = c.CreateState(); break; case GateComponent c: _gateStates[itemId] = c.CreateState(); break; @@ -83,21 +103,20 @@ internal void Register(T item) where T : MonoBehaviour } } - internal void Schedule(InputAction action) - { - _inputActions.Enqueue(action); - } + #endregion + + #region Event Functions private void Awake() { _player = GetComponent(); + _insideOfs = new InsideOfs(Allocator.Persistent); } private void Start() { // init state var env = new PhysicsEnv(NowUsec, GetComponent()); - _insideOfs = new InsideOfs(Allocator.Persistent); // create static octree var sw = Stopwatch.StartNew(); @@ -126,11 +145,9 @@ private void Start() Debug.Log($"Octree of {_colliders.Value.Colliders.Length} constructed (colliders: {elapsedMs}ms, tree: {sw.Elapsed.TotalMilliseconds}ms)."); // get balls - var balls = GetComponentsInChildren(); - _balls = new NativeParallelHashMap(balls.Length, Allocator.Persistent); + var balls = GetComponentsInChildren(); foreach (var ball in balls) { - _balls.Add(ball.Id, ball.Data); - _ballLookup[ball.Id] = ball; + Register(ball); } _eventQueue = new NativeQueue(Allocator.Persistent); @@ -138,15 +155,6 @@ private void Start() _physicsEnv[0] = env; } - private static BlobAssetReference AllocateColliders(ref ColliderReference managedColliders) - { - var allocateColliderJob = new ColliderAllocationJob(ref managedColliders); - allocateColliderJob.Run(); - var colliders = allocateColliderJob.BlobAsset[0]; - allocateColliderJob.Dispose(); - return colliders; - } - private void Update() { // prepare job @@ -159,7 +167,7 @@ private void Update() Colliders = _colliders, InsideOfs = _insideOfs, Events = events, - Balls = _balls, + Balls = _ballStates, BumperStates = _bumperStates, DropTargetStates = _dropTargetStates, FlipperStates = _flipperStates, @@ -173,7 +181,7 @@ private void Update() }; var env = _physicsEnv[0]; - var state = new PhysicsState(ref env, ref _octree, ref _colliders, ref events, ref _insideOfs, ref _balls, + var state = new PhysicsState(ref env, ref _octree, ref _colliders, ref events, ref _insideOfs, ref _ballStates, ref _bumperStates, ref _dropTargetStates, ref _flipperStates, ref _gateStates, ref _hitTargetStates, ref _kickerStates, ref _plungerStates, ref _spinnerStates, ref _surfaceStates, ref _triggerStates); @@ -193,7 +201,7 @@ private void Update() } // retrieve updated data - _balls = updatePhysics.Balls; + _ballStates = updatePhysics.Balls; _physicsEnv = updatePhysics.PhysicsEnv; _flipperStates = updatePhysics.FlipperStates; @@ -203,7 +211,7 @@ private void Update() using (var enumerator = state.Balls.GetEnumerator()) { while (enumerator.MoveNext()) { ref var ball = ref enumerator.Current.Value; - BallMovementPhysics.Move(ball, _ballLookup[ball.Id].transform); + BallMovementPhysics.Move(ball, _transforms[ball.Id]); } } @@ -304,10 +312,25 @@ private void OnDestroy() { _physicsEnv.Dispose(); _eventQueue.Dispose(); - _balls.Dispose(); + _ballStates.Dispose(); _colliders.Dispose(); _insideOfs.Dispose(); } + + #endregion + + #region Helpers + + private static BlobAssetReference AllocateColliders(ref ColliderReference managedColliders) + { + var allocateColliderJob = new ColliderAllocationJob(ref managedColliders); + allocateColliderJob.Run(); + var colliders = allocateColliderJob.BlobAsset[0]; + allocateColliderJob.Dispose(); + return colliders; + } + + #endregion } [BurstCompile(CompileSynchronously = true)] diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 8ffd3beee..486a26aa7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -144,7 +144,7 @@ private void Awake() _apis.Add(TableApi); - BallManager = new BallManager(this); + BallManager = new BallManager(GetComponentInChildren(), this, Playfield.transform); _inputManager = new InputManager(); _inputManager.Enable(HandleInput); @@ -497,14 +497,9 @@ public void OnEvent(in EventData eventData) // } } - internal void BallCreated(Entity ballEntity, GameObject ball) - { - OnBallCreated?.Invoke(this, new BallEvent(ballEntity, ball)); - } - internal void BallDestroyed(Entity ballEntity, GameObject ball) - { - OnBallDestroyed?.Invoke(this, new BallEvent(ballEntity, ball)); - } + internal void BallCreated(int ballId, GameObject ball) => OnBallCreated?.Invoke(this, new BallEvent(ballId, ball)); + + internal void BallDestroyed(int ballId, GameObject ball) => OnBallDestroyed?.Invoke(this, new BallEvent(ballId, ball)); #endregion @@ -603,12 +598,12 @@ private static void HandleInput(object obj, InputActionChange change) public readonly struct BallEvent { - public readonly Entity BallEntity; + public readonly int BallId; public readonly GameObject Ball; - public BallEvent(Entity ballEntity, GameObject ball) + public BallEvent(int ballId, GameObject ball) { - BallEntity = ballEntity; + BallId = ballId; Ball = ball; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs index 726d28e18..92e943a9c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs @@ -67,12 +67,12 @@ public void Init(TableComponent tableComponent, BallManager ballManager) _worldToLocal = transform.worldToLocalMatrix; } - public void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, - in float3 localVel, in float scale, in float mass, in float radius, in int kickerId) - { - _ballManager.CreateEntity(ballGo, id, in worldPos, in localPos, in localVel,scale * radius * 2, - in mass, in radius, in kickerId); - } + // public void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, + // in float3 localVel, in float scale, in float mass, in float radius, in int kickerId) + // { + // _ballManager.CreateEntity(ballGo, id, in worldPos, in localPos, in localVel,scale * radius * 2, + // in mass, in radius, in kickerId); + // } public void BallManualRoll(in Entity entity, in float3 targetWorldPosition) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs index 6fda9c46b..7596b4d51 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs @@ -16,7 +16,6 @@ using Unity.Entities; using Unity.Mathematics; -using UnityEngine; using VisualPinball.Engine.Common; namespace VisualPinball.Unity @@ -49,8 +48,8 @@ public interface IPhysicsEngine : IEngine /// Physics mass /// Radius in local space /// If created within a kicker, this is the kicker entity - void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, in float3 localVel, - in float scale, in float mass, in float radius, in int kickerId); + // void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, in float3 localVel, + // in float scale, in float mass, in float radius, in int kickerId); /// /// Rolls the ball manually to a position on the playfield. diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs similarity index 78% rename from VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs index 55ba24ae5..76aed330e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs @@ -1,54 +1,46 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable InconsistentNaming - -using System; -using Unity.Mathematics; -using UnityEngine; - -namespace VisualPinball.Unity -{ - public class PhysicsBall : MonoBehaviour - { - public float Radius = 25; - public float Mass = 1; - - [NonSerialized] - public int Id; - - private void Awake() - { - var player = GetComponentInParent(); - if (player) { - Id = player.NextBallId; - } - } - - internal BallData Data => new BallData { - Id = Id, - IsFrozen = false, - Position = transform.localPosition.TranslateToVpx(), - Radius = Radius, - Mass = Mass, - Velocity = float3.zero, - BallOrientation = float3x3.identity, - BallOrientationForUnity = float3x3.identity, - RingCounterOldPos = 0, - AngularMomentum = float3.zero - }; - } -} +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable InconsistentNaming + +using Unity.Mathematics; +using UnityEngine; + +namespace VisualPinball.Unity +{ + public class BallComponent : MonoBehaviour + { + public int Id => gameObject.GetInstanceID(); + public float Radius = 25; + public float Mass = 1; + public float3 Velocity; + public bool IsFrozen; + + + internal BallData CreateState() => new BallData { + Id = Id, + IsFrozen = IsFrozen, + Position = transform.localPosition.TranslateToVpx(), + Radius = Radius, + Mass = Mass, + Velocity = Velocity, + BallOrientation = float3x3.identity, + BallOrientationForUnity = float3x3.identity, + RingCounterOldPos = 0, + AngularMomentum = float3.zero + }; + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs.meta similarity index 97% rename from VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs.meta index 2b5b35122..1b96be544 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsBall.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs.meta @@ -1,3 +1,3 @@ -fileFormatVersion: 2 -guid: a04fca20ce2246b9abf456441b587efd +fileFormatVersion: 2 +guid: a04fca20ce2246b9abf456441b587efd timeCreated: 1678725159 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs index a239e0351..a4c1f20c9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs @@ -24,6 +24,10 @@ internal static class BallDisplacementPhysics { internal static void UpdateDisplacements(ref BallData ball, float dTime) { + if (ball.IsFrozen) { + return; + } + ball.Position += ball.Velocity * dTime; var inertia = ball.Inertia; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index 8be95caeb..533623543 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -15,12 +15,8 @@ // along with this program. If not, see . using System; -using Unity.Entities; -using Unity.Mathematics; using UnityEngine; -using VisualPinball.Engine.Common; using VisualPinball.Engine.Game; -using VisualPinballUnity; using Object = UnityEngine.Object; namespace VisualPinball.Unity @@ -32,19 +28,16 @@ namespace VisualPinball.Unity public class BallManager { public int NumBallsCreated { get; private set; } - public int NumBalls { get; private set; } - private readonly GameObject _playfield; + private readonly PhysicsEngine _physicsEngine; private readonly Player _player; + private readonly Transform _parent; - private static EntityManager EntityManager => World.DefaultGameObjectInjectionWorld.EntityManager; - - private static Mesh _unitySphereMesh; // used to cache ball mesh from GameObject - - public BallManager(Player player) + public BallManager(PhysicsEngine physicsEngine, Player player, Transform parent) { + _physicsEngine = physicsEngine; _player = player; - _playfield = player.Playfield; + _parent = parent; } public void CreateBall(IBallCreationPosition ballCreator, float radius = 25f, float mass = 1f) @@ -55,104 +48,33 @@ public void CreateBall(IBallCreationPosition ballCreator, float radius = 25f, fl public void CreateBall(IBallCreationPosition ballCreator, float radius, float mass, int kickerId) { var localPos = ballCreator.GetBallCreationPosition().ToUnityFloat3(); - var localVel = ballCreator.GetBallCreationVelocity().ToUnityFloat3(); localPos.z += radius; - var ltw = _playfield.transform.localToWorldMatrix; - var worldPos = ltw.MultiplyPoint(localPos); - var scale3 = new Vector3( - ltw.GetColumn(0).magnitude, - ltw.GetColumn(1).magnitude, - ltw.GetColumn(2).magnitude - ); - var scale = (scale3.x + scale3.y + scale3.z) / 3.0f; // scale is only scale (without radiusfloat now, not vector. - var ballId = NumBallsCreated++; var ballPrefab = RenderPipeline.Current.BallConverter.CreateDefaultBall(); - var ballGo = Object.Instantiate(ballPrefab, _playfield.transform); - ballGo.name = $"Ball{ballId}"; + var ballGo = Object.Instantiate(ballPrefab, _parent); + var ballComp = ballGo.GetComponent(); + ballGo.name = $"Ball {ballId}"; ballGo.transform.localScale = Physics.ScaleToWorld(new Vector3(radius, radius, radius) * 2f); - ballGo.transform.localPosition = localPos; + ballGo.transform.localPosition = localPos.TranslateToWorld(); + ballComp.Radius = radius; + ballComp.Mass = mass; + ballComp.Velocity = ballCreator.GetBallCreationVelocity().ToUnityFloat3(); + ballComp.IsFrozen = kickerId != 0; - // create ball entity - EngineProvider - .Get() - .BallCreate(ballGo, ballId, worldPos, localPos, localVel, scale, mass, radius, kickerId); - } - - public void CreateEntity(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, in float3 localVel, in float scale, - in float mass, in float radius, in int kickerId) - { - // Efficiently instantiate a bunch of entities from the already converted entity prefab - var entity = EntityManager.CreateEntity( - typeof(OverlappingStaticColliderBufferElement), - typeof(OverlappingDynamicBufferElement), - typeof(BallInsideOfBufferElement), - //typeof(BallLastPositionsBufferElement), - typeof(BallData), - typeof(CollisionEventData) - ); - -#if UNITY_EDITOR - EntityManager.SetName(entity, $"Ball{id}"); -#endif - - _player.Balls[kickerId] = ballGo; - - var world = World.DefaultGameObjectInjectionWorld; - // var ecbs = world.GetOrCreateSystemManaged(); - // var ecb = ecbs.CreateCommandBuffer(); - // - // ecb.AddBuffer(entity); - // ecb.AddBuffer(entity); - // ecb.AddBuffer(entity); - // - // ecb.AddComponent(entity, new BallData { - // Id = id, - // IsFrozen = kickerId != 0, - // Position = localPos, - // Radius = radius, - // Mass = mass, - // Velocity = localVel, - // BallOrientation = float3x3.identity, - // BallOrientationForUnity = float3x3.identity, - // RingCounterOldPos = 0, - // AngularMomentum = float3.zero, - // LastPositions = new BallPositions(new float3(float.MaxValue, float.MaxValue, float.MaxValue)) - // }); - // - // ecb.AddComponent(entity, new CollisionEventData { - // HitTime = -1, - // HitDistance = 0, - // HitFlag = false, - // IsContact = false, - // HitNormal = new float3(0, 0, 0), - // }); - // - // var lastBallPostBuffer = ecb.AddBuffer(entity); - // for (var i = 0; i < BallRingCounterPhysics.MaxBallTrailPos; i++) { - // lastBallPostBuffer.Add(new BallLastPositionsBufferElement - // { Value = new float3(float.MaxValue, float.MaxValue, float.MaxValue) } - // ); - // } + // register ball + _physicsEngine.Register(ballComp); + _player.BallCreated(ballGo.GetInstanceID(), ballGo); // handle inside-kicker creation if (kickerId != 0) { - // fixme job - // var kickerData = EntityManager.GetComponentData(kickerEntity); - // if (!kickerData.FallThrough) { - // var kickerCollData = EntityManager.GetComponentData(kickerEntity); - // var inside = ecb.AddBuffer(entity); - // BallData.SetInsideOf(ref inside, kickerEntity); - // kickerCollData.BallId = entity; - // kickerCollData.LastCapturedBallId = entity; - // ecb.SetComponent(kickerEntity, kickerCollData); - // } + ref var kickerData = ref _physicsEngine.KickerState(kickerId); + if (!kickerData.Static.FallThrough) { + _physicsEngine.SetBallInsideOf(ballComp.Id, kickerId); + kickerData.Collision.BallId = ballComp.Id; + kickerData.Collision.LastCapturedBallId = ballComp.Id; + } } - - NumBalls++; - - _player.BallCreated(entity, ballGo); } public void DestroyEntity(int ballId) @@ -173,26 +95,5 @@ public void DestroyEntity(int ballId) // // NumBalls--; } - - /// - /// Dirty way to get SphereMesh from Unity. - /// ToDo: Get Mesh from our resources - /// - /// Sphere Mesh - private static Mesh GetSphereMesh() - { - if (!_unitySphereMesh) - { - var go = GameObject.CreatePrimitive(PrimitiveType.Sphere); - _unitySphereMesh = go.GetComponent().sharedMesh; - Object.Destroy(go); - } - - return _unitySphereMesh; - } - - #region Material - - #endregion } } From a3391f8086e0f1c0ed2b4bc18d3c29826466f866 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 12 Oct 2023 23:38:22 +0200 Subject: [PATCH 083/159] jobs: Fix item API registration. --- .../VisualPinball.Unity/Game/Player.cs | 142 ++++++++---------- .../Physics/Event/EventData.cs | 12 +- .../VPT/Kicker/KickerComponent.cs | 4 - 3 files changed, 68 insertions(+), 90 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 486a26aa7..debc0d9e0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -23,6 +23,7 @@ using UnityEngine; using UnityEngine.InputSystem; using VisualPinball.Engine.Common; +using VisualPinball.Engine.Game; using VisualPinball.Engine.Game.Engines; using VisualPinball.Engine.VPT.Trigger; using VisualPinballUnity; @@ -63,38 +64,28 @@ public class Player : MonoBehaviour public bool UpdateDuringGamplay = true; // table related - private readonly List _apis = new List(); - private readonly List _colliderGenerators = new List(); - private readonly Dictionary _hittables = new Dictionary(); - private readonly Dictionary _rotatables = new Dictionary(); - private readonly Dictionary _collidables = new Dictionary(); - private readonly Dictionary _spinnables = new Dictionary(); - private readonly Dictionary _slingshots = new Dictionary(); - private readonly Dictionary _droppables = new Dictionary(); - - internal readonly Dictionary FlipperTransforms = new Dictionary(); - internal readonly Dictionary BumperSkirtTransforms = new Dictionary(); - internal readonly Dictionary BumperRingTransforms = new Dictionary(); - internal readonly Dictionary GateWireTransforms = new Dictionary(); - internal readonly Dictionary HitTargetTransforms = new Dictionary(); - internal readonly Dictionary DropTargetTransforms = new Dictionary(); - internal readonly Dictionary SpinnerPlateTransforms = new Dictionary(); - internal readonly Dictionary TriggerTransforms = new Dictionary(); - internal readonly Dictionary Balls = new Dictionary(); + private readonly List _apis = new(); + private readonly List _colliderGenerators = new(); + private readonly Dictionary _hittables = new(); + private readonly Dictionary _rotatables = new(); + private readonly Dictionary _collidables = new(); + private readonly Dictionary _spinnables = new(); + private readonly Dictionary _slingshots = new(); + private readonly Dictionary _droppables = new(); internal IEnumerable ColliderGenerators => _colliderGenerators; // input related [NonSerialized] private InputManager _inputManager; [NonSerialized] private VisualPinballSimulationSystemGroup _simulationSystemGroup; - [NonSerialized] private readonly List<(InputAction, Action)> _actions = new List<(InputAction, Action)>(); + [NonSerialized] private readonly List<(InputAction, Action)> _actions = new(); // players - [NonSerialized] private readonly LampPlayer _lampPlayer = new LampPlayer(); - [NonSerialized] private readonly CoilPlayer _coilPlayer = new CoilPlayer(); - [NonSerialized] private readonly SwitchPlayer _switchPlayer = new SwitchPlayer(); - [NonSerialized] private readonly WirePlayer _wirePlayer = new WirePlayer(); - [NonSerialized] private readonly DisplayPlayer _displayPlayer = new DisplayPlayer(); + [NonSerialized] private readonly LampPlayer _lampPlayer = new(); + [NonSerialized] private readonly CoilPlayer _coilPlayer = new(); + [NonSerialized] private readonly SwitchPlayer _switchPlayer = new(); + [NonSerialized] private readonly WirePlayer _wirePlayer = new(); + [NonSerialized] private readonly DisplayPlayer _displayPlayer = new(); private const float SlowMotionMax = 0.1f; private const float TimeLapseMax = 2.5f; @@ -103,7 +94,7 @@ public class Player : MonoBehaviour private TableComponent _tableComponent; private PlayfieldComponent _playfieldComponent; - internal static readonly Entity PlayfieldEntity = new Entity {Index = -3, Version = 0}; // a fake entity we just use for reference + internal static readonly Entity PlayfieldEntity = new() {Index = -3, Version = 0}; // a fake entity we just use for reference #region Access @@ -218,15 +209,11 @@ private void OnDestroy() public void RegisterBumper(BumperComponent component) { Register(new BumperApi(component.gameObject, this), component); - RegisterTransform(BumperRingTransforms, component); - RegisterTransform(BumperSkirtTransforms, component); } public void RegisterFlipper(FlipperComponent component) { Register(new FlipperApi(component.gameObject, this), component); - FlipperTransforms[component.gameObject.GetInstanceID()] = component.gameObject.transform; - if (EngineProvider.Exists) { EngineProvider.Get().OnRegisterFlipper(component.GetInstanceID(), component.gameObject.name); } @@ -235,13 +222,11 @@ public void RegisterFlipper(FlipperComponent component) public void RegisterDropTarget(DropTargetComponent component) { Register(new DropTargetApi(component.gameObject, this), component); - RegisterTransform(DropTargetTransforms, component); } public void RegisterGate(GateComponent component) { Register(new GateApi(component.gameObject, this), component); - RegisterTransform(GateWireTransforms, component); } public void RegisterGateLifter(GateLifterComponent component) @@ -252,7 +237,6 @@ public void RegisterGateLifter(GateLifterComponent component) public void RegisterHitTarget(HitTargetComponent component) { Register(new HitTargetApi(component.gameObject, this), component); - RegisterTransform(HitTargetTransforms, component); } public void RegisterKicker(KickerComponent component) @@ -314,7 +298,7 @@ public void RegisterPlayfield(GameObject go) public void RegisterPrimitive(PrimitiveComponent component) { - Register(new PrimitiveApi(component.gameObject, this), component, component.gameObject.GetInstanceID()); + Register(new PrimitiveApi(component.gameObject, this), component); } public void RegisterRamp(RampComponent component) @@ -330,7 +314,6 @@ public void RegisterRubber(RubberComponent component) public void RegisterSpinner(SpinnerComponent component) { Register(new SpinnerApi(component.gameObject, this), component); - RegisterTransform(SpinnerPlateTransforms, component); } public void RegisterSurface(SurfaceComponent component) @@ -346,7 +329,6 @@ public void RegisterTeleporter(TeleporterComponent component) public void RegisterTrigger(TriggerComponent component) { Register(new TriggerApi(component.gameObject, this), component); - TriggerTransforms[component.GetInstanceID()] = component.gameObject.transform; } public void RegisterTrigger(TriggerData data, GameObject go) @@ -366,10 +348,11 @@ public void RegisterMetalWireGuide(MetalWireGuideComponent component) Register(new MetalWireGuideApi(component.gameObject, this), component); } - private void Register(TApi api, MonoBehaviour component, int itemId = 0) where TApi : IApi + private void Register(TApi api, MonoBehaviour component) where TApi : IApi { TableApi.Register(component, api); _apis.Add(api); + var itemId = component.gameObject.GetInstanceID(); if (api is IApiRotatable rotatable) { _rotatables[itemId] = rotatable; } @@ -451,50 +434,49 @@ private void RegisterCollider(int itemId, IApiColliderGenerator apiColl) public void OnEvent(in EventData eventData) { Debug.Log(eventData); - // todo re-enable - // switch (eventData.eventId) { - // case EventId.HitEventsHit: - // if (!_hittables.ContainsKey(eventData.ItemId)) { - // Debug.LogError($"Cannot find item {eventData.ItemId} in hittables."); - // } - // _hittables[eventData.ItemId].OnHit(eventData.BallId); - // break; - // - // case EventId.HitEventsUnhit: - // _hittables[eventData.ItemId].OnHit(eventData.BallId, true); - // break; - // - // case EventId.LimitEventsBos: - // _rotatables[eventData.ItemId].OnRotate(eventData.FloatParam, false); - // break; - // - // case EventId.LimitEventsEos: - // _rotatables[eventData.ItemId].OnRotate(eventData.FloatParam, true); - // break; - // - // case EventId.SpinnerEventsSpin: - // _spinnables[eventData.ItemId].OnSpin(); - // break; - // - // case EventId.FlipperEventsCollide: - // _collidables[eventData.ItemId].OnCollide(eventData.BallId, eventData.FloatParam); - // break; - // - // case EventId.SurfaceEventsSlingshot: - // _slingshots[eventData.ItemId].OnSlingshot(eventData.BallId); - // break; - // - // case EventId.TargetEventsDropped: - // _droppables[eventData.ItemId].OnDropStatusChanged(true, eventData.BallId); - // break; - // - // case EventId.TargetEventsRaised: - // _droppables[eventData.ItemId].OnDropStatusChanged(false, eventData.BallId); - // break; - // - // default: - // throw new InvalidOperationException($"Unknown event {eventData.eventId} for entity {eventData.ItemId}"); - // } + switch (eventData.EventId) { + case EventId.HitEventsHit: + if (!_hittables.ContainsKey(eventData.ItemId)) { + Debug.LogError($"Cannot find item {eventData.ItemId} in hittables."); + } + _hittables[eventData.ItemId].OnHit(eventData.BallId); + break; + + case EventId.HitEventsUnhit: + _hittables[eventData.ItemId].OnHit(eventData.BallId, true); + break; + + case EventId.LimitEventsBos: + _rotatables[eventData.ItemId].OnRotate(eventData.FloatParam, false); + break; + + case EventId.LimitEventsEos: + _rotatables[eventData.ItemId].OnRotate(eventData.FloatParam, true); + break; + + case EventId.SpinnerEventsSpin: + _spinnables[eventData.ItemId].OnSpin(); + break; + + case EventId.FlipperEventsCollide: + _collidables[eventData.ItemId].OnCollide(eventData.BallId, eventData.FloatParam); + break; + + case EventId.SurfaceEventsSlingshot: + _slingshots[eventData.ItemId].OnSlingshot(eventData.BallId); + break; + + case EventId.TargetEventsDropped: + _droppables[eventData.ItemId].OnDropStatusChanged(true, eventData.BallId); + break; + + case EventId.TargetEventsRaised: + _droppables[eventData.ItemId].OnDropStatusChanged(false, eventData.BallId); + break; + + default: + throw new InvalidOperationException($"Unknown event {eventData.EventId} for entity {eventData.ItemId}"); + } } internal void BallCreated(int ballId, GameObject ball) => OnBallCreated?.Invoke(this, new BallEvent(ballId, ball)); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs index d9400e282..e00fc834c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs @@ -25,7 +25,7 @@ namespace VisualPinball.Unity /// public readonly struct EventData { - public readonly EventId eventId; + public readonly EventId EventId; public readonly int ItemId; public readonly int BallId; public readonly float FloatParam; @@ -33,7 +33,7 @@ public readonly struct EventData public EventData(EventId eventId, int itemId, int ballId, bool groupEvent = false) : this() { - this.eventId = eventId; + EventId = eventId; ItemId = itemId; BallId = ballId; GroupEvent = groupEvent; @@ -41,7 +41,7 @@ public EventData(EventId eventId, int itemId, int ballId, bool groupEvent = fals public EventData(EventId eventId, int itemId, int ballId, float floatParam, bool groupEvent = false) : this() { - this.eventId = eventId; + EventId = eventId; ItemId = itemId; BallId = ballId; FloatParam = floatParam; @@ -51,7 +51,7 @@ public EventData(EventId eventId, int itemId, int ballId, float floatParam, bool public EventData(EventId eventId, int itemId, bool groupEvent = false) : this() { - this.eventId = eventId; + this.EventId = eventId; ItemId = itemId; BallId = 0; GroupEvent = groupEvent; @@ -59,13 +59,13 @@ public EventData(EventId eventId, int itemId, bool groupEvent = false) : this() public EventData(EventId eventId, int itemId, float floatParam, bool groupEvent = false) : this() { - this.eventId = eventId; + this.EventId = eventId; ItemId = itemId; BallId = 0; FloatParam = floatParam; GroupEvent = groupEvent; } - public override string ToString() => $"Event {eventId} for item {ItemId} by ball {BallId} ({FloatParam})"; + public override string ToString() => $"Event {EventId} for item {ItemId} by ball {BallId} ({FloatParam})"; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs index ac7d76b20..dacebf764 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs @@ -25,8 +25,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using Unity.Collections; -using Unity.Entities; using Unity.Mathematics; using UnityEditor; using UnityEngine; @@ -261,8 +259,6 @@ public override void CopyFromObject(GameObject go) #region State - internal bool HasState => GetComponent(); - internal KickerState CreateState() { // collision From c0146a426030cded4b3cb557e437877190587be4 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 13 Oct 2023 00:14:12 +0200 Subject: [PATCH 084/159] jobs: Fix kicker ball creation. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 1 + .../VisualPinball.Unity/Game/Player.cs | 36 ++-- .../VPT/Ball/BallManager.cs | 2 +- .../VPT/Bumper/BumperApi.cs | 2 +- .../VPT/Bumper/BumperColliderComponent.cs | 4 +- .../VisualPinball.Unity/VPT/CollidableApi.cs | 2 +- .../VPT/ColliderComponent.cs | 8 +- .../VPT/Flipper/FlipperApi.cs | 2 +- .../VPT/Flipper/FlipperColliderComponent.cs | 4 +- .../VisualPinball.Unity/VPT/Gate/GateApi.cs | 2 +- .../VPT/Gate/GateColliderComponent.cs | 4 +- .../VPT/HitTarget/DropTargetApi.cs | 2 +- .../HitTarget/DropTargetColliderComponent.cs | 4 +- .../VPT/HitTarget/HitTargetApi.cs | 2 +- .../HitTarget/HitTargetColliderComponent.cs | 4 +- .../VisualPinball.Unity/VPT/ItemApi.cs | 6 +- .../VPT/Kicker/KickerApi.cs | 175 ++++++++---------- .../VPT/Kicker/KickerColliderComponent.cs | 4 +- .../VisualPinball.Unity/VPT/Light/LightApi.cs | 2 +- .../VPT/Light/LightComponent.cs | 2 +- .../VPT/MetalWireGuide/MetalWireGuideApi.cs | 2 +- .../MetalWireGuideColliderComponent.cs | 4 +- .../VPT/Playfield/PlayfieldApi.cs | 2 +- .../Playfield/PlayfieldColliderComponent.cs | 4 +- .../VPT/Plunger/PlungerApi.cs | 2 +- .../VPT/Plunger/PlungerColliderComponent.cs | 4 +- .../VPT/Primitive/PrimitiveApi.cs | 2 +- .../Primitive/PrimitiveColliderComponent.cs | 4 +- .../VisualPinball.Unity/VPT/Ramp/RampApi.cs | 2 +- .../VPT/Ramp/RampColliderComponent.cs | 4 +- .../VPT/Rubber/RubberApi.cs | 2 +- .../VPT/Rubber/RubberColliderComponent.cs | 4 +- .../VPT/Spinner/SpinnerApi.cs | 2 +- .../VPT/Spinner/SpinnerColliderComponent.cs | 4 +- .../VPT/Surface/SurfaceApi.cs | 2 +- .../VPT/Surface/SurfaceColliderComponent.cs | 4 +- .../VPT/Trigger/TriggerApi.cs | 3 +- .../VPT/Trigger/TriggerColliderComponent.cs | 4 +- .../VPT/Trough/TroughApi.cs | 4 +- 39 files changed, 150 insertions(+), 177 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 80d3e9b3b..14d9c2571 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -72,6 +72,7 @@ public class PhysicsEngine : MonoBehaviour internal delegate void InputAction(ref PhysicsState state); internal void Schedule(InputAction action) => _inputActions.Enqueue(action); + internal ref BallData BallState(int itemId) => ref _ballStates.GetValueByRef(itemId); internal ref KickerState KickerState(int itemId) => ref _kickerStates.GetValueByRef(itemId); internal void SetBallInsideOf(int ballId, int itemId) => _insideOfs.SetInsideOf(itemId, ballId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index debc0d9e0..58fe54a79 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -93,6 +93,7 @@ public class Player : MonoBehaviour private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private TableComponent _tableComponent; private PlayfieldComponent _playfieldComponent; + private PhysicsEngine _physicsEngine; internal static readonly Entity PlayfieldEntity = new() {Index = -3, Version = 0}; // a fake entity we just use for reference @@ -131,6 +132,7 @@ private void Awake() DebugLogger.ClearLog(); _tableComponent = GetComponent(); _playfieldComponent = GetComponentInChildren(); + _physicsEngine = GetComponent(); var engineComponent = GetComponent(); _apis.Add(TableApi); @@ -208,12 +210,12 @@ private void OnDestroy() public void RegisterBumper(BumperComponent component) { - Register(new BumperApi(component.gameObject, this), component); + Register(new BumperApi(component.gameObject, this, _physicsEngine), component); } public void RegisterFlipper(FlipperComponent component) { - Register(new FlipperApi(component.gameObject, this), component); + Register(new FlipperApi(component.gameObject, this, _physicsEngine), component); if (EngineProvider.Exists) { EngineProvider.Get().OnRegisterFlipper(component.GetInstanceID(), component.gameObject.name); } @@ -221,12 +223,12 @@ public void RegisterFlipper(FlipperComponent component) public void RegisterDropTarget(DropTargetComponent component) { - Register(new DropTargetApi(component.gameObject, this), component); + Register(new DropTargetApi(component.gameObject, this, _physicsEngine), component); } public void RegisterGate(GateComponent component) { - Register(new GateApi(component.gameObject, this), component); + Register(new GateApi(component.gameObject, this, _physicsEngine), component); } public void RegisterGateLifter(GateLifterComponent component) @@ -236,12 +238,12 @@ public void RegisterGateLifter(GateLifterComponent component) public void RegisterHitTarget(HitTargetComponent component) { - Register(new HitTargetApi(component.gameObject, this), component); + Register(new HitTargetApi(component.gameObject, this, _physicsEngine), component); } public void RegisterKicker(KickerComponent component) { - Register(new KickerApi(component.gameObject, this), component); + Register(new KickerApi(component.gameObject, this, _physicsEngine), component); } public void RegisterLamp(LightComponent component) @@ -281,7 +283,7 @@ public void RegisterSlingshotComponent(SlingshotComponent component) public void RegisterPlunger(PlungerComponent component, InputActionReference actionRef) { - var plungerApi = new PlungerApi(component.gameObject, this); + var plungerApi = new PlungerApi(component.gameObject, this, _physicsEngine); Register(plungerApi, component); if (actionRef != null) { @@ -292,33 +294,33 @@ public void RegisterPlunger(PlungerComponent component, InputActionReference act public void RegisterPlayfield(GameObject go) { - PlayfieldApi = new PlayfieldApi(go, this); + PlayfieldApi = new PlayfieldApi(go, this, _physicsEngine); _colliderGenerators.Add(PlayfieldApi); } public void RegisterPrimitive(PrimitiveComponent component) { - Register(new PrimitiveApi(component.gameObject, this), component); + Register(new PrimitiveApi(component.gameObject, this, _physicsEngine), component); } public void RegisterRamp(RampComponent component) { - Register(new RampApi(component.gameObject, this), component); + Register(new RampApi(component.gameObject, this, _physicsEngine), component); } public void RegisterRubber(RubberComponent component) { - Register(new RubberApi(component.gameObject, this), component); + Register(new RubberApi(component.gameObject, this, _physicsEngine), component); } public void RegisterSpinner(SpinnerComponent component) { - Register(new SpinnerApi(component.gameObject, this), component); + Register(new SpinnerApi(component.gameObject, this, _physicsEngine), component); } public void RegisterSurface(SurfaceComponent component) { - Register(new SurfaceApi(component.gameObject, this), component); + Register(new SurfaceApi(component.gameObject, this, _physicsEngine), component); } public void RegisterTeleporter(TeleporterComponent component) @@ -328,24 +330,24 @@ public void RegisterTeleporter(TeleporterComponent component) public void RegisterTrigger(TriggerComponent component) { - Register(new TriggerApi(component.gameObject, this), component); + Register(new TriggerApi(component.gameObject, this, _physicsEngine), component); } public void RegisterTrigger(TriggerData data, GameObject go) { var component = go.AddComponent(); component.SetData(data); - Register(new TriggerApi(go, this), component); + Register(new TriggerApi(go, this, _physicsEngine), component); } public void RegisterTrough(TroughComponent component) { - Register(new TroughApi(component.gameObject, this), component); + Register(new TroughApi(component.gameObject, this, _physicsEngine), component); } public void RegisterMetalWireGuide(MetalWireGuideComponent component) { - Register(new MetalWireGuideApi(component.gameObject, this), component); + Register(new MetalWireGuideApi(component.gameObject, this, _physicsEngine), component); } private void Register(TApi api, MonoBehaviour component) where TApi : IApi diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index 533623543..c8a176da7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -77,7 +77,7 @@ public void CreateBall(IBallCreationPosition ballCreator, float radius, float ma } } - public void DestroyEntity(int ballId) + public void DestroyBall(int ballId) { // fixme job // var ballGo = _player.Balls[ballEntity]; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs index 5cbff8dd4..6eed53ebc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs @@ -39,7 +39,7 @@ public class BumperApi : CollidableApi public event EventHandler Switch; - public BumperApi(GameObject go, Player player) : base(go, player) + public BumperApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs index 1cf66593d..4fe40be3a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs @@ -43,8 +43,8 @@ public class BumperColliderComponent : ColliderComponent new BumperApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new BumperApi(gameObject, player, physicsEngine); public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(scatterAngleDeg: Scatter); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs index 86b2c75cb..3e4981c3b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs @@ -45,7 +45,7 @@ public bool IsCollidable private protected EntityManager EntityManager; private readonly SimulateCycleSystemGroup _simulateCycleSystemGroup; - protected CollidableApi(GameObject go, Player player) : base(go, player) + protected CollidableApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { if (World.DefaultGameObjectInjectionWorld != null) { _simulateCycleSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index cde84193f..ff585319a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -64,7 +64,7 @@ public abstract class ColliderComponent : SubComponent _nonMeshColliders = new List(); [NonSerialized] private bool _collidersDirty; - protected abstract IApiColliderGenerator InstantiateColliderApi(Player player); + protected abstract IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine); public abstract PhysicsMaterialData PhysicsMaterialData { get; } @@ -126,7 +126,7 @@ private void OnDrawGizmos() var generateColliders = ShowAabbs || showColliders && !HasCachedColliders; if (generateColliders) { - var api = InstantiateColliderApi(player); + var api = InstantiateColliderApi(player, null); var colliders = new ColliderReference(Allocator.TempJob); api.CreateColliders(ref colliders, 0.1f); @@ -146,7 +146,7 @@ private void OnDrawGizmos() } if (ShowColliderOctree) { - var api = InstantiateColliderApi(player); + var api = InstantiateColliderApi(player, null); var colliders = new ColliderReference(Allocator.TempJob); api.CreateColliders(ref colliders, 0.1f); @@ -432,7 +432,7 @@ private static void DrawAabb(Aabb aabb, bool isSelected) void ICollidableComponent.GetColliders(Player player, ref ColliderReference colliders, float margin) { - InstantiateColliderApi(player).CreateColliders(ref colliders, margin); + InstantiateColliderApi(player, null).CreateColliders(ref colliders, margin); } #endif } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs index f519892e1..ba01a2aa6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs @@ -71,7 +71,7 @@ public class FlipperApi : CollidableApi new FlipperApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new FlipperApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs index 1938f31ff..575e3cdea 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs @@ -72,7 +72,7 @@ public class GateApi : CollidableApi, public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(Elasticity, friction: Friction); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new GateApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new GateApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs index 5ad342965..5c7e661bb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs @@ -54,7 +54,7 @@ public bool IsDropped set => SetIsDropped(value); } - internal DropTargetApi(GameObject go, Player player) : base(go, player) + internal DropTargetApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs index 54d155efb..3177dd3f0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs @@ -60,7 +60,7 @@ public class DropTargetColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new DropTargetApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new DropTargetApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs index b0b6542f1..ae3818139 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetApi.cs @@ -39,7 +39,7 @@ public class HitTargetApi : CollidableApi public event EventHandler Switch; - internal HitTargetApi(GameObject go, Player player) : base(go, player) + internal HitTargetApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs index 9fc9cb2f1..1615d987f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs @@ -56,7 +56,7 @@ public class HitTargetColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new HitTargetApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new HitTargetApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs index 5e5677f48..c2b07fef0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs @@ -42,19 +42,19 @@ public abstract class ItemApi private protected TableApi TableApi => Player.TableApi; - internal VisualPinballSimulationSystemGroup SimulationSystemGroup => World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); - private protected readonly Player Player; + private protected readonly PhysicsEngine PhysicsEngine; private protected readonly SwitchHandler SwitchHandler; private protected BallManager BallManager; private protected TableComponent TableComponent; - protected ItemApi(GameObject go, Player player) + protected ItemApi(GameObject go, Player player, PhysicsEngine physicsEngine) { GameObject = go; MainComponent = go.GetComponent(); Player = player; SwitchHandler = new SwitchHandler(Name, player); + PhysicsEngine = physicsEngine; } protected void OnInit(BallManager ballManager) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs index 0dde647a0..d87caab19 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs @@ -16,9 +16,7 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.VPT.Kicker; @@ -55,7 +53,7 @@ public class KickerApi : CollidableApi _coils = new Dictionary(); - public KickerApi(GameObject go, Player player) : base(go, player) + public KickerApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { foreach (var coil in MainComponent.Coils) { _coils[coil.Id] = new KickerDeviceCoil(player, coil, this); @@ -89,7 +87,7 @@ public void CreateSizedBall(float radius) public void Kick(float angle, float speed, float inclination = 0) { - SimulationSystemGroup.QueueAfterBallCreation(() => KickXYZ(ItemId, angle, speed, inclination, 0, 0, 0)); + KickXYZ(angle, speed, inclination, 0, 0, 0); } /// @@ -101,14 +99,11 @@ public void Kick(float angle, float speed, float inclination = 0) /// public void DestroyBall() { - // fixme job - // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - // var kickerCollisionData = entityManager.GetComponentData(Entity); - // var ballEntity = kickerCollisionData.BallId; - // if (ballEntity != Entity.Null) { - // BallManager.DestroyEntity(ballEntity); - // SimulationSystemGroup.QueueAfterBallCreation(OnBallDestroyed); - // } + ref var kickerState = ref PhysicsEngine.KickerState(ItemId); + if (kickerState.Collision.HasBall) { + BallManager.DestroyBall(kickerState.Collision.BallId); + OnBallDestroyed(); + } } /// @@ -117,33 +112,20 @@ public void DestroyBall() /// True if there is a ball in the kicker, false otherwise. public bool HasBall() { - // fixme job - // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - // var kickerCollisionData = entityManager.GetComponentData(Entity); - // return kickerCollisionData.HasBall; - return false; + ref var kickerState = ref PhysicsEngine.KickerState(ItemId); + return kickerState.Collision.HasBall; } - internal BallData GetBallData() + internal ref BallData GetBallData() { - // fixme job - // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - // var kickerCollisionData = entityManager.GetComponentData(Entity); - // return kickerCollisionData.HasBall - // ? entityManager.GetComponentData(kickerCollisionData.BallId) - // : default; - return default; + ref var kickerState = ref PhysicsEngine.KickerState(ItemId); + return ref PhysicsEngine.BallState(kickerState.Collision.BallId); } - internal int BallId - { - get - { - return 0; - // fixme job - // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - // var kickerCollisionData = entityManager.GetComponentData(Entity); - // return kickerCollisionData.BallId; + internal int BallId { + get { + ref var kickerState = ref PhysicsEngine.KickerState(ItemId); + return kickerState.Collision.BallId; } } @@ -169,79 +151,68 @@ private IApiCoil Coil(string deviceItem) private void OnBallDestroyed() { - // fixme job - // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - // var kickerCollisionData = entityManager.GetComponentData(Entity); - // if (kickerCollisionData.BallId != 0) { - // - // // update kicker status - // kickerCollisionData.BallId = kickerCollisionData.BallId; - // entityManager.SetComponentData(Entity, kickerCollisionData); - // } + ref var kickerState = ref PhysicsEngine.KickerState(ItemId); + if (kickerState.Collision.HasBall) { + kickerState.Collision.BallId = 0; + } } #endregion - private void KickXYZ(int kickerId, float angle, float speed, float inclination, float x, float y, float z) + private void KickXYZ(float angle, float speed, float inclination, float x, float y, float z) { - // fixme jobs - // var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - // var kickerCollisionData = entityManager.GetComponentData(kickerEntity); - // var kickerStaticData = entityManager.GetComponentData(kickerEntity); - // var ballEntity = kickerCollisionData.BallId; - // if (ballEntity != Entity.Null) { - // var angleRad = math.radians(angle); // yaw angle, zero is along -Y axis - // - // if (math.abs(inclination) > (float) (System.Math.PI / 2.0)) { - // // radians or degrees? if greater PI/2 assume degrees - // inclination *= (float) (System.Math.PI / 180.0); // convert to radians - // } - // - // // if < 0 use global value - // var scatterAngle = kickerStaticData.Scatter < 0.0f ? 0.0f : math.radians(kickerStaticData.Scatter); - // scatterAngle *= TableComponent.GlobalDifficulty; // apply difficulty weighting - // - // if (scatterAngle > 1.0e-5f) { // ignore near zero angles - // var scatter = new Random().NextFloat(-1f, 1f); // -1.0f..1.0f - // scatter *= (1.0f - scatter * scatter) * 2.59808f * scatterAngle; // shape quadratic distribution and scale - // angleRad += scatter; - // } - // - // var speedZ = math.sin(inclination) * speed; - // if (speedZ > 0.0f) { - // speed *= math.cos(inclination); - // } - // - // // update ball data - // var ballData = entityManager.GetComponentData(ballEntity); - // ballData.Position = new float3( - // ballData.Position.x + x, - // ballData.Position.y + y, - // ballData.Position.z + z - // ); - // ballData.Velocity = new float3( - // math.sin(angleRad) * speed, - // -math.cos(angleRad) * speed, - // speedZ - // ); - // ballData.IsFrozen = false; - // ballData.AngularMomentum = float3.zero; - // entityManager.SetComponentData(ballEntity, ballData); - // - // // update collision event - // var collEvent = entityManager.GetComponentData(ballEntity); - // collEvent.HitDistance = 0.0f; - // collEvent.HitTime = -1.0f; - // collEvent.HitNormal = float3.zero; - // collEvent.HitVelocity = float2.zero; - // collEvent.HitFlag = false; - // collEvent.IsContact = false; - // entityManager.SetComponentData(ballEntity, collEvent); - // - // // update kicker status - // kickerCollisionData.BallId = Entity.Null; - // entityManager.SetComponentData(kickerEntity, kickerCollisionData); - // } + ref var kickerState = ref PhysicsEngine.KickerState(ItemId); + var ballId = kickerState.Collision.BallId; + if (ballId != 0) { + var angleRad = math.radians(angle); // yaw angle, zero is along -Y axis + + if (math.abs(inclination) > (float) (System.Math.PI / 2.0)) { + // radians or degrees? if greater PI/2 assume degrees + inclination *= (float) (System.Math.PI / 180.0); // convert to radians + } + + // if < 0 use global value + var scatterAngle = kickerState.Static.Scatter < 0.0f ? 0.0f : math.radians(kickerState.Static.Scatter); + scatterAngle *= TableComponent.GlobalDifficulty; // apply difficulty weighting + + if (scatterAngle > 1.0e-5f) { // ignore near zero angles + var scatter = new Random().NextFloat(-1f, 1f); // -1.0f..1.0f + scatter *= (1.0f - scatter * scatter) * 2.59808f * scatterAngle; // shape quadratic distribution and scale + angleRad += scatter; + } + + var speedZ = math.sin(inclination) * speed; + if (speedZ > 0.0f) { + speed *= math.cos(inclination); + } + + // update ball data + ref var ballData = ref PhysicsEngine.BallState(ballId); + ballData.Position = new float3( + ballData.Position.x + x, + ballData.Position.y + y, + ballData.Position.z + z + ); + ballData.Velocity = new float3( + math.sin(angleRad) * speed, + -math.cos(angleRad) * speed, + speedZ + ); + ballData.IsFrozen = false; + ballData.AngularMomentum = float3.zero; + + // update collision event + ref var collEvent = ref ballData.CollisionEvent; + collEvent.HitDistance = 0.0f; + collEvent.HitTime = -1.0f; + collEvent.HitNormal = float3.zero; + collEvent.HitVelocity = float2.zero; + collEvent.HitFlag = false; + collEvent.IsContact = false; + + // update kicker status + kickerState.Collision.BallId = 0; + } } IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => AddSwitchDest(switchConfig.WithPulse(false), switchStatus); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs index 8a3ef7faa..c02f036c2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs @@ -51,7 +51,7 @@ public class KickerColliderComponent : ColliderComponent GetPhysicsMaterialData(scatterAngleDeg: Scatter); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new KickerApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new KickerApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightApi.cs index aa5d7377b..45eada226 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightApi.cs @@ -91,7 +91,7 @@ public void OnLamp(Color color) IApiWireDest IApiWireDeviceDest.Wire(string deviceItem) => this; - internal LightApi(GameObject go, Player player) : base(go, player) + internal LightApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { _lightComponent = go.GetComponentInChildren(); _status = _lightComponent.State; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightComponent.cs index f5150f67d..290537fc0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightComponent.cs @@ -92,7 +92,7 @@ public class LightComponent : MainRenderableComponent, ILampDeviceCom #region API - public IApiLamp GetApi(Player player) => _api ??= new LightApi(gameObject, player); + public IApiLamp GetApi(Player player) => _api ??= new LightApi(gameObject, player, null); public IEnumerable LightSources => GetComponentsInChildren(); public Color LampColor => _color; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs index d9054bca5..2a26c3aba 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideApi.cs @@ -34,7 +34,7 @@ public class MetalWireGuideApi : CollidableApi public event EventHandler Hit; - internal MetalWireGuideApi(GameObject go, Player player) : base(go, player) + internal MetalWireGuideApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs index 53cba3fa2..435bbe97b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs @@ -56,7 +56,7 @@ public class MetalWireGuideColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new MetalWireGuideApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new MetalWireGuideApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs index e306e846a..1f969e87d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs @@ -25,7 +25,7 @@ namespace VisualPinball.Unity { public class PlayfieldApi : CollidableApi { - internal PlayfieldApi(GameObject go, Player player) : base(go, player) + internal PlayfieldApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs index e5d04059e..ff302d14a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs @@ -54,7 +54,7 @@ public class PlayfieldColliderComponent : ColliderComponent GetPhysicsMaterialData(0, 0); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new PlayfieldApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new PlayfieldApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs index 7ab6f5504..6dc349244 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs @@ -61,7 +61,7 @@ public class PlungerApi : CollidableApi GetPhysicsMaterialData(); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new PlungerApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new PlungerApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs index 9325eef5d..af5a106f1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveApi.cs @@ -34,7 +34,7 @@ public class PrimitiveApi : CollidableApi public event EventHandler Hit; - internal PrimitiveApi(GameObject go, Player player) : base(go, player) + internal PrimitiveApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs index f3b6157ab..6a6ca03a2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs @@ -60,7 +60,7 @@ public class PrimitiveColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new PrimitiveApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new PrimitiveApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs index 6ad1a87b0..66752d069 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampApi.cs @@ -33,7 +33,7 @@ public class RampApi : CollidableApi public event EventHandler Hit; - internal RampApi(GameObject go, Player player) : base(go, player) + internal RampApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs index 2f4eb7366..217d3e97e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs @@ -61,7 +61,7 @@ public class RampColliderComponent : ColliderComponent #endregion public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(Elasticity, friction: Friction, scatterAngleDeg: Scatter, overwrite: OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new RampApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new RampApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs index 564c4d9c3..2d92b9260 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberApi.cs @@ -34,7 +34,7 @@ public class RubberApi : CollidableApi public event EventHandler Hit; - internal RubberApi(GameObject go, Player player) : base(go, player) + internal RubberApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs index 7443ccd4c..b69957394 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs @@ -56,7 +56,7 @@ public class RubberColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new RubberApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new RubberApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs index 554d09988..5e6849fc7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs @@ -65,7 +65,7 @@ public class SpinnerApi : CollidableApi public event EventHandler Switch; - public SpinnerApi(GameObject go, Player player) : base(go, player) + public SpinnerApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs index 5b1431ce1..5b6ad81a5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs @@ -35,7 +35,7 @@ public class SpinnerColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new SpinnerApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new SpinnerApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs index e9c90ebc4..25f804dac 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceApi.cs @@ -39,7 +39,7 @@ public class SurfaceApi : CollidableApi public event EventHandler Slingshot; - internal SurfaceApi(GameObject go, Player player) : base(go, player) + internal SurfaceApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs index 7bf9ccec5..cb6035f99 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs @@ -68,7 +68,7 @@ public class SurfaceColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new SurfaceApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new SurfaceApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs index 524d61fcd..4e053be94 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerApi.cs @@ -44,8 +44,7 @@ public class TriggerApi : CollidableApi public event EventHandler Switch; - internal TriggerApi(GameObject go, Player player) - : base(go, player) + internal TriggerApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs index 36afaf9e5..39afe21a5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs @@ -52,7 +52,7 @@ public class TriggerColliderComponent : ColliderComponent GetPhysicsMaterialData(); - protected override IApiColliderGenerator InstantiateColliderApi(Player player) - => new TriggerApi(gameObject, player); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) + => new TriggerApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs index bba383824..772478639 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs @@ -165,7 +165,7 @@ public class TroughApi : ItemApi, /// public event EventHandler Init; - internal TroughApi(GameObject go, Player player) : base(go, player) + internal TroughApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { } @@ -291,7 +291,7 @@ private void OnEntry(object sender, SwitchEventArgs args) if (_drainSwitch is KickerApi kickerApi) { kickerApi.DestroyBall(); } else { - BallManager.DestroyEntity(args.BallId); + BallManager.DestroyBall(args.BallId); } DrainBall(); From e2c63d8599f897c17d2da53e974c580e46e7dfca Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 13 Oct 2023 20:49:39 +0200 Subject: [PATCH 085/159] jobs: Ditch IPhysicsEngine abstraction. --- .../Common/EngineTests.cs | 67 ------ .../Inspectors/PlayerInspector.cs | 2 - .../VisualPinball.Unity/Game/PhysicsEngine.cs | 3 + .../VisualPinball.Unity/Game/PhysicsEnv.cs | 1 + .../VisualPinball.Unity/Game/Player.cs | 3 - .../Physics/Engine/DefaultPhysicsEngine.cs | 190 ------------------ .../Engine/DefaultPhysicsEngine.cs.meta | 11 - .../Physics/Engine/IPhysicsEngine.cs | 99 --------- .../Physics/Engine/IPhysicsEngine.cs.meta | 11 - .../SystemGroup/SimulateCycleSystemGroup.cs | 9 - .../VPT/Flipper/FlipperApi.cs | 10 +- 11 files changed, 12 insertions(+), 394 deletions(-) delete mode 100644 VisualPinball.Engine.Test/Common/EngineTests.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs.meta diff --git a/VisualPinball.Engine.Test/Common/EngineTests.cs b/VisualPinball.Engine.Test/Common/EngineTests.cs deleted file mode 100644 index 29f9fe087..000000000 --- a/VisualPinball.Engine.Test/Common/EngineTests.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using FluentAssertions; -using NUnit.Framework; -using VisualPinball.Engine.Common; - -namespace VisualPinball.Engine.Test.Common -{ - public class EngineTests - { - [Test] - public void ShouldFailIfNoneSet() - { - Action act = () => EngineProvider.Get(); - act.Should().Throw() - .WithMessage("Must select VisualPinball.Engine.Test.Common.ITestEngine engine before retrieving!"); - } - - [Test] - public void ShouldProvideIfSet() - { - EngineProvider.Set("VisualPinball.Engine.Test.Common.TestEngine1"); - var engine = EngineProvider.Get(); - - engine.Should().NotBeNull(); - engine.Name.Should().Be("Engine 1"); - - EngineProvider.Set("VisualPinball.Engine.Test.Common.TestEngine2"); - engine = EngineProvider.Get(); - - engine.Should().NotBeNull(); - engine.Name.Should().Be("Engine 2"); - } - } - - internal interface ITestEngine : IEngine - { - - } - - internal class TestEngine1 : ITestEngine - { - - public string Name { get; } = "Engine 1"; - } - - internal class TestEngine2 : ITestEngine - { - - public string Name { get; } = "Engine 2"; - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs index ae7b0fd4b..90baee1c3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs @@ -25,7 +25,6 @@ namespace VisualPinball.Unity.Editor [CanEditMultipleObjects] public class PlayerInspector : UnityEditor.Editor { - private IPhysicsEngine[] _physicsEngines; private string[] _physicsEngineNames; private int _physicsEngineIndex; @@ -50,7 +49,6 @@ public override void OnInspectorGUI() if (player == null) { return; } - DrawEngineSelector("Physics Engine", ref player.physicsEngineId, ref _physicsEngines, ref _physicsEngineNames, ref _physicsEngineIndex); DrawEngineSelector("Debug UI", ref player.debugUiId, ref _debugUIs, ref _debugUINames, ref _debugUIIndex); if (_toggleDebug = EditorGUILayout.BeginFoldoutHeaderGroup(_toggleDebug, "Debug")) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 14d9c2571..f3b9d1b33 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -73,8 +73,10 @@ public class PhysicsEngine : MonoBehaviour internal void Schedule(InputAction action) => _inputActions.Enqueue(action); internal ref BallData BallState(int itemId) => ref _ballStates.GetValueByRef(itemId); + internal ref FlipperState FlipperState(int itemId) => ref _flipperStates.GetValueByRef(itemId); internal ref KickerState KickerState(int itemId) => ref _kickerStates.GetValueByRef(itemId); internal void SetBallInsideOf(int ballId, int itemId) => _insideOfs.SetInsideOf(itemId, ballId); + internal uint TimeMsec => _physicsEnv[0].TimeMsec; internal void Register(T item) where T : MonoBehaviour { @@ -489,6 +491,7 @@ public void Execute() env.CurPhysicsFrameTime = env.NextPhysicsFrameTime; env.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; + env.TimeMsec = timeMsec; } PhysicsEnv[0] = env; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs index 13348a4db..e0bcc3519 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs @@ -27,6 +27,7 @@ public struct PhysicsEnv : IDisposable public readonly ulong StartTimeUsec; public ulong CurPhysicsFrameTime; public ulong NextPhysicsFrameTime; + public uint TimeMsec; public Random Random; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 58fe54a79..85627f6e7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -58,7 +58,6 @@ public class Player : MonoBehaviour public event EventHandler OnBallDestroyed; [HideInInspector] [SerializeField] public string debugUiId; - [HideInInspector] [SerializeField] public string physicsEngineId; [Tooltip("When enabled, update the switch, coil, lamp and wire manager windows in the editor (slower performance)")] public bool UpdateDuringGamplay = true; @@ -150,8 +149,6 @@ private void Awake() _displayPlayer.Awake(GamelogicEngine); } - EngineProvider.Set(physicsEngineId); - EngineProvider.Get().Init(_tableComponent, BallManager); if (!string.IsNullOrEmpty(debugUiId)) { EngineProvider.Set(debugUiId); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs deleted file mode 100644 index 92e943a9c..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs +++ /dev/null @@ -1,190 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using Unity.Assertions; -using Unity.Collections; -using Unity.Entities; -using Unity.Mathematics; -using UnityEngine; -using VisualPinball.Engine.Common; -using VisualPinball.Unity.Collections; -using VisualPinballUnity; - -namespace VisualPinball.Unity -{ - public class DefaultPhysicsEngine : IPhysicsEngine - { - public string Name => "Default VPX"; - - public BallManager _ballManager; - - private EntityManager _entityManager; - // private EntityQuery _flipperDataQuery; - // private EntityQuery _ballDataQuery; - - private Matrix4x4 _worldToLocal; - private DebugFlipperState[] _flipperStates = new DebugFlipperState[0]; - private readonly DebugFlipperSlider[] _flipperSliders = new DebugFlipperSlider[0]; - private int _nextBallIdToNotifyDebugUI; - - private VisualPinballSimulationSystemGroup _visualPinballSimulationSystemGroup; - private TableComponent _tableComponent; - - public void Init(TableComponent tableComponent, BallManager ballManager) - { - _tableComponent = tableComponent; - _ballManager = ballManager; - _entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - // _flipperDataQuery = _entityManager.CreateEntityQuery( - // ComponentType.ReadOnly(), - // ComponentType.ReadOnly(), - // ComponentType.ReadOnly() - // ); - // - // _ballDataQuery = _entityManager.CreateEntityQuery(ComponentType.ReadOnly()); - - _visualPinballSimulationSystemGroup = _entityManager.World.GetOrCreateSystemManaged(); - var simulateCycleSystemGroup = _entityManager.World.GetOrCreateSystemManaged(); - - _visualPinballSimulationSystemGroup.Enabled = true; - simulateCycleSystemGroup.PhysicsEngine = this; // needed for flipper status update we don't do in all engines - - var transform = tableComponent.gameObject.transform; - _worldToLocal = transform.worldToLocalMatrix; - } - - // public void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, - // in float3 localVel, in float scale, in float mass, in float radius, in int kickerId) - // { - // _ballManager.CreateEntity(ballGo, id, in worldPos, in localPos, in localVel,scale * radius * 2, - // in mass, in radius, in kickerId); - // } - - public void BallManualRoll(in Entity entity, in float3 targetWorldPosition) - { - // fail safe, if we get invalid entity - if (entity == Entity.Null && entity.Index != -1) { - return; - } - - float3 target = _worldToLocal.MultiplyPoint(targetWorldPosition); - var ballData = _entityManager.GetComponentData(entity); - ballData.Velocity = float3.zero; - ballData.AngularMomentum = float3.zero; - ballData.IsFrozen = false; - - var dir = (target - ballData.Position); - var dist = math.length(dir); - if (dist > 50) { - dist = 50; - } - if (dist > 0.1f) { - dist += 1.0f; - ballData.Velocity = dir * dist * 0.001f; - _entityManager.SetComponentData(entity, ballData); - } - } - - public void FlipperRotateToEnd(in int itemId) - { - var id = itemId; - var physicsEngine = _tableComponent.GetComponent(); - physicsEngine.Schedule((ref PhysicsState state) => { - var timeMsec = (uint)((state.Env.CurPhysicsFrameTime - state.Env.StartTimeUsec) / 1000); - ref var flipperState = ref state.FlipperStates.GetValueByRef(id); - flipperState.Movement.EnableRotateEvent = 1; - flipperState.Movement.StartRotateToEndTime = timeMsec; - flipperState.Movement.AngleAtRotateToEnd = flipperState.Movement.Angle; - flipperState.Solenoid.Value = true; - }); - } - - public void FlipperRotateToStart(in int itemId) - { - var id = itemId; - var physicsEngine = _tableComponent.GetComponent(); - physicsEngine.Schedule((ref PhysicsState state) => { - ref var flipperState = ref state.FlipperStates.GetValueByRef(id); - flipperState.Movement.EnableRotateEvent = -1; - flipperState.Solenoid.Value = false; - }); - } - - public DebugFlipperState[] FlipperGetDebugStates() - { - return _flipperStates; - } - - public DebugFlipperSlider[] FlipperGetDebugSliders() - { - return _flipperSliders; - } - - public void SetFlipperDebugValue(DebugFlipperSliderParam param, float v) - { - throw new InvalidOperationException("No debug values for default engine."); - } - - public float GetFlipperDebugValue(DebugFlipperSliderParam param) - { - throw new InvalidOperationException("No debug values for default engine."); - } - - public void UpdateDebugFlipperStates() - { - // // for each flipper - // var entities = _flipperDataQuery.ToEntityArray(Allocator.TempJob); - // if (_flipperStates.Length == 0) { - // _flipperStates = new DebugFlipperState[entities.Length]; - // } - // for (var i = 0; i < entities.Length; i++) { - // var entity = entities[i]; - // var movementData = _entityManager.GetComponentData(entity); - // var staticData = _entityManager.GetComponentData(entity); - // var solenoidData = _entityManager.GetComponentData(entity); - // _flipperStates[i] = new DebugFlipperState( - // entity, - // math.degrees(math.abs(movementData.Angle - staticData.AngleStart)), - // solenoidData.Value - // ); - // } - // entities.Dispose(); - } - - public void PushPendingCreateBallNotifications() - { - if (_nextBallIdToNotifyDebugUI == _ballManager.NumBallsCreated) - return; // nothing to report - - // var entities = _ballDataQuery.ToEntityArray(Allocator.TempJob); - // int numBallsToReport = _ballManager.NumBallsCreated - _nextBallIdToNotifyDebugUI; - // foreach (var entity in entities) - // { - // var ballData = _entityManager.GetComponentData(entity); - // if (ballData.Id >= _nextBallIdToNotifyDebugUI) - // { - // EngineProvider.Get().OnCreateBall(entity); - // --numBallsToReport; - // } - // } - - // // error checking - // Assert.AreEqual(0, numBallsToReport); - // _nextBallIdToNotifyDebugUI = _ballManager.NumBallsCreated; - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs.meta deleted file mode 100644 index 8dc5cf98d..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/DefaultPhysicsEngine.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a5cceab61b91d3841981ea53976c8b42 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs deleted file mode 100644 index 7596b4d51..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; -using VisualPinball.Engine.Common; - -namespace VisualPinball.Unity -{ - /// - /// A swappable engine that implements VPE's rigid body physics. - /// - public interface IPhysicsEngine : IEngine - { - /// - /// Initialize and enable the engine. - /// - /// - /// All engines are instantiated, but they should only activate - /// themselves when this method is called. - /// - /// - /// - void Init(TableComponent tableComponent, BallManager ballManager); - - /// - /// Create a new ball and returns its entity. - /// - /// Created game object of the ball - /// Unique ID of the ball - /// Position in world space - /// Position in local space - /// Velocity in local space - /// Scale relative to ball mesh - /// Physics mass - /// Radius in local space - /// If created within a kicker, this is the kicker entity - // void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, in float3 localVel, - // in float scale, in float mass, in float radius, in int kickerId); - - /// - /// Rolls the ball manually to a position on the playfield. - /// - /// Ball entity - /// New position in world space - void BallManualRoll(in Entity ballEntity, in float3 targetWorldPosition); - - /// - /// Rotate the flipper "up" (button pressed) - /// - /// - void FlipperRotateToEnd(in int itemId); - - /// - /// Rotate the flipper "down" (button released) - /// - /// - void FlipperRotateToStart(in int itemId); - - /// - /// Returns a simplified version of all flipper states for the - /// debug UI to deal with. - /// - /// All flipper states - DebugFlipperState[] FlipperGetDebugStates(); - - /// - /// Returns which sliders for flippers the debug UI should display. - /// - DebugFlipperSlider[] FlipperGetDebugSliders(); - - /// - /// Updates a flipper property during gameplay. - /// - /// Which property to update - /// New value - void SetFlipperDebugValue(DebugFlipperSliderParam param, float v); - - /// - /// Retrieves a flipper property during gameplay. - /// - /// Which property to retrieve - /// Value of the property - float GetFlipperDebugValue(DebugFlipperSliderParam param); - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs.meta deleted file mode 100644 index e7de09b88..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Engine/IPhysicsEngine.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6f7bfff55a6e64543bf6c269ad5e0d49 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs index e024cd477..965af8223 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs @@ -42,8 +42,6 @@ internal partial class SimulateCycleSystemGroup : ComponentSystemGroup public NativeHashMap ItemsColliding; - public DefaultPhysicsEngine PhysicsEngine; - public override IReadOnlyList Systems => _systemsToUpdate; public NativeList Contacts; @@ -154,13 +152,6 @@ private void UpdateCycle() SwapBallCollisionHandling = !SwapBallCollisionHandling; ++numSteps; } - - // debug ui update - if (EngineProvider.Exists) { - PhysicsEngine.UpdateDebugFlipperStates(); - PhysicsEngine.PushPendingCreateBallNotifications(); - EngineProvider.Get().OnPhysicsUpdate(_simulationSystemGroup.CurrentPhysicsTime, numSteps, (float)_simulationTime.Elapsed.TotalMilliseconds); - } } private void ClearContacts() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs index ba01a2aa6..c52ba1891 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs @@ -94,7 +94,11 @@ void IApi.OnDestroy() /// public void RotateToEnd() { - EngineProvider.Get().FlipperRotateToEnd(ItemId); + ref var state = ref PhysicsEngine.FlipperState(ItemId); + state.Movement.EnableRotateEvent = 1; + state.Movement.StartRotateToEndTime = PhysicsEngine.TimeMsec; + state.Movement.AngleAtRotateToEnd = state.Movement.Angle; + state.Solenoid.Value = true; } /// @@ -103,7 +107,9 @@ public void RotateToEnd() /// public void RotateToStart() { - EngineProvider.Get().FlipperRotateToStart(ItemId); + ref var state = ref PhysicsEngine.FlipperState(ItemId); + state.Movement.EnableRotateEvent = -1; + state.Solenoid.Value = false; } internal float StartAngle From 4dd2cbd965264ccbe33800aab51b42f03f2797ad Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 13 Oct 2023 21:03:22 +0200 Subject: [PATCH 086/159] jobs: Move physics jobs into separate files. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 171 +---------------- .../Game/PhysicsPopulateJob.cs | 23 +++ .../Game/PhysicsPopulateJob.cs.meta | 3 + .../Game/PhysicsUpdateJob.cs | 173 ++++++++++++++++++ .../Game/PhysicsUpdateJob.cs.meta | 3 + .../VisualPinball.Unity/VPT/CollidableApi.cs | 11 -- .../VPT/ColliderComponent.cs | 2 +- .../VPT/Flipper/FlipperApi.cs | 2 + 8 files changed, 208 insertions(+), 180 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index f3b9d1b33..ba16bfbab 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -17,13 +17,11 @@ using System.Collections.Generic; using System.Diagnostics; using NativeTrees; -using Unity.Burst; using Unity.Collections; using Unity.Entities; using Unity.Jobs; using Unity.Mathematics; using UnityEngine; -using VisualPinball.Engine.Common; using VisualPinball.Unity.Collections; using VisualPinballUnity; using Debug = UnityEngine.Debug; @@ -51,6 +49,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeParallelHashMap _spinnerStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _surfaceStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _triggerStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashSet _nonCollidableItems = new(0, Allocator.Persistent); #endregion @@ -77,7 +76,6 @@ public class PhysicsEngine : MonoBehaviour internal ref KickerState KickerState(int itemId) => ref _kickerStates.GetValueByRef(itemId); internal void SetBallInsideOf(int ballId, int itemId) => _insideOfs.SetInsideOf(itemId, ballId); internal uint TimeMsec => _physicsEnv[0].TimeMsec; - internal void Register(T item) where T : MonoBehaviour { var go = item.gameObject; @@ -139,7 +137,7 @@ private void Start() _octree = new NativeOctree(playfieldBounds, 1024, 10, Allocator.Persistent); sw.Restart(); - var populateJob = new PopulatePhysicsJob { + var populateJob = new PhysicsPopulateJob { Colliders = _colliders, Octree = _octree, }; @@ -162,7 +160,7 @@ private void Update() { // prepare job var events = _eventQueue.AsParallelWriter(); - var updatePhysics = new UpdatePhysicsJob { + var updatePhysics = new PhysicsUpdateJob { InitialTimeUsec = NowUsec, DeltaTimeMs = Time.deltaTime * 1000, PhysicsEnv = _physicsEnv, @@ -335,167 +333,4 @@ private static BlobAssetReference AllocateColliders(ref ColliderRe #endregion } - - [BurstCompile(CompileSynchronously = true)] - internal struct PopulatePhysicsJob : IJob - { - [ReadOnly] - public BlobAssetReference Colliders; - public NativeOctree Octree; - - public void Execute() - { - for (var i = 0; i < Colliders.Value.Colliders.Length; i++) { - Octree.Insert(Colliders.GetId(i), Colliders.GetAabb(i)); - } - } - } - - [BurstCompile(CompileSynchronously = true)] - internal struct UpdatePhysicsJob : IJob - { - [ReadOnly] - public ulong InitialTimeUsec; - - public float DeltaTimeMs; - - public NativeArray PhysicsEnv; - public NativeOctree Octree; - public BlobAssetReference Colliders; - public InsideOfs InsideOfs; - public NativeQueue.ParallelWriter Events; - - public NativeParallelHashMap Balls; - public NativeParallelHashMap BumperStates; - public NativeParallelHashMap DropTargetStates; - public NativeParallelHashMap FlipperStates; - public NativeParallelHashMap GateStates; - public NativeParallelHashMap HitTargetStates; - public NativeParallelHashMap KickerStates; - public NativeParallelHashMap PlungerStates; - public NativeParallelHashMap SpinnerStates; - public NativeParallelHashMap SurfaceStates; - public NativeParallelHashMap TriggerStates; - - public void Execute() - { - var env = PhysicsEnv[0]; - var state = new PhysicsState(ref env, ref Octree, ref Colliders, ref Events, ref InsideOfs, ref Balls, - ref BumperStates, ref DropTargetStates, ref FlipperStates, ref GateStates, - ref HitTargetStates, ref KickerStates, ref PlungerStates, ref SpinnerStates, - ref SurfaceStates, ref TriggerStates); - var cycle = new PhysicsCycle(Allocator.Temp); - - while (env.CurPhysicsFrameTime < InitialTimeUsec) // loop here until current (real) time matches the physics (simulated) time - { - var timeMsec = (uint)((env.CurPhysicsFrameTime - env.StartTimeUsec) / 1000); - var physicsDiffTime = (float)((env.NextPhysicsFrameTime - env.CurPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); - - // update velocities - always on integral physics frame boundary (spinner, gate, flipper, plunger, ball) - #region Update Velocities - - // balls - using (var enumerator = state.Balls.GetEnumerator()) { - while (enumerator.MoveNext()) { - BallVelocityPhysics.UpdateVelocities(ref enumerator.Current.Value, env.Gravity); - } - } - // flippers - using (var enumerator = FlipperStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - FlipperVelocityPhysics.UpdateVelocities(ref enumerator.Current.Value); - } - } - // gates - using (var enumerator = GateStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - ref var gateState = ref enumerator.Current.Value; - GateVelocityPhysics.UpdateVelocities(ref gateState.Movement, in gateState.Static); - } - } - // plungers - using (var enumerator = PlungerStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - ref var plungerState = ref enumerator.Current.Value; - PlungerVelocityPhysics.UpdateVelocities(ref plungerState.Movement, ref plungerState.Velocity, in plungerState.Static); - } - } - // spinners - using (var enumerator = SpinnerStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - ref var spinnerState = ref enumerator.Current.Value; - SpinnerVelocityPhysics.UpdateVelocities(ref spinnerState.Movement, in spinnerState.Static); - } - } - - #endregion - - // primary physics loop - cycle.Simulate(ref state, physicsDiffTime, timeMsec); - - // ball trail, keep old pos of balls - using (var enumerator = state.Balls.GetEnumerator()) { - while (enumerator.MoveNext()) { - BallRingCounterPhysics.Update(ref enumerator.Current.Value); - } - } - - #region Animation - - // bumper - using (var enumerator = BumperStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - ref var bumperState = ref enumerator.Current.Value; - if (bumperState.RingItemId != 0) { - BumperRingAnimation.Update(ref bumperState.RingAnimation, DeltaTimeMs); - } - if (bumperState.SkirtItemId != 0) { - BumperSkirtAnimation.Update(ref bumperState.SkirtAnimation, DeltaTimeMs); - } - } - } - - // drop target - using (var enumerator = DropTargetStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - ref var dropTargetState = ref enumerator.Current.Value; - DropTargetAnimation.Update(enumerator.Current.Key, ref dropTargetState.Animation, in dropTargetState.Static, ref state, timeMsec); - } - } - - // hit target - using (var enumerator = HitTargetStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - ref var hitTargetState = ref enumerator.Current.Value; - HitTargetAnimation.Update(ref hitTargetState.Animation, in hitTargetState.Static, timeMsec); - } - } - - // plunger - using (var enumerator = PlungerStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - ref var plungerState = ref enumerator.Current.Value; - PlungerAnimation.Update(ref plungerState.Animation, in plungerState.Movement, in plungerState.Static); - } - } - - // trigger - using (var enumerator = TriggerStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - ref var triggerState = ref enumerator.Current.Value; - TriggerAnimation.Update(ref triggerState.Animation, ref triggerState.Movement, in triggerState.Static, DeltaTimeMs); - } - } - - #endregion - - env.CurPhysicsFrameTime = env.NextPhysicsFrameTime; - env.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; - env.TimeMsec = timeMsec; - } - - PhysicsEnv[0] = env; - cycle.Dispose(); - } - } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs new file mode 100644 index 000000000..cefbde893 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs @@ -0,0 +1,23 @@ +using NativeTrees; +using Unity.Burst; +using Unity.Collections; +using Unity.Entities; +using Unity.Jobs; + +namespace VisualPinball.Unity +{ + [BurstCompile(CompileSynchronously = true)] + internal struct PhysicsPopulateJob : IJob + { + [ReadOnly] + public BlobAssetReference Colliders; + public NativeOctree Octree; + + public void Execute() + { + for (var i = 0; i < Colliders.Value.Colliders.Length; i++) { + Octree.Insert(Colliders.GetId(i), Colliders.GetAabb(i)); + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs.meta new file mode 100644 index 000000000..97f223edf --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0d5b69cfa7a94e9885f48041fcd5af9a +timeCreated: 1697223597 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs new file mode 100644 index 000000000..2517123c4 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs @@ -0,0 +1,173 @@ +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using NativeTrees; +using Unity.Burst; +using Unity.Collections; +using Unity.Entities; +using Unity.Jobs; +using VisualPinball.Engine.Common; +using VisualPinballUnity; + +namespace VisualPinball.Unity +{ + [BurstCompile(CompileSynchronously = true)] + internal struct PhysicsUpdateJob : IJob + { + [ReadOnly] + public ulong InitialTimeUsec; + + public float DeltaTimeMs; + + public NativeArray PhysicsEnv; + public NativeOctree Octree; + public BlobAssetReference Colliders; + public InsideOfs InsideOfs; + public NativeQueue.ParallelWriter Events; + + public NativeParallelHashMap Balls; + public NativeParallelHashMap BumperStates; + public NativeParallelHashMap DropTargetStates; + public NativeParallelHashMap FlipperStates; + public NativeParallelHashMap GateStates; + public NativeParallelHashMap HitTargetStates; + public NativeParallelHashMap KickerStates; + public NativeParallelHashMap PlungerStates; + public NativeParallelHashMap SpinnerStates; + public NativeParallelHashMap SurfaceStates; + public NativeParallelHashMap TriggerStates; + + public void Execute() + { + var env = PhysicsEnv[0]; + var state = new PhysicsState(ref env, ref Octree, ref Colliders, ref Events, ref InsideOfs, ref Balls, + ref BumperStates, ref DropTargetStates, ref FlipperStates, ref GateStates, + ref HitTargetStates, ref KickerStates, ref PlungerStates, ref SpinnerStates, + ref SurfaceStates, ref TriggerStates); + var cycle = new PhysicsCycle(Allocator.Temp); + + while (env.CurPhysicsFrameTime < InitialTimeUsec) // loop here until current (real) time matches the physics (simulated) time + { + var timeMsec = (uint)((env.CurPhysicsFrameTime - env.StartTimeUsec) / 1000); + var physicsDiffTime = (float)((env.NextPhysicsFrameTime - env.CurPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); + + // update velocities - always on integral physics frame boundary (spinner, gate, flipper, plunger, ball) + #region Update Velocities + + // balls + using (var enumerator = state.Balls.GetEnumerator()) { + while (enumerator.MoveNext()) { + BallVelocityPhysics.UpdateVelocities(ref enumerator.Current.Value, env.Gravity); + } + } + // flippers + using (var enumerator = FlipperStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + FlipperVelocityPhysics.UpdateVelocities(ref enumerator.Current.Value); + } + } + // gates + using (var enumerator = GateStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var gateState = ref enumerator.Current.Value; + GateVelocityPhysics.UpdateVelocities(ref gateState.Movement, in gateState.Static); + } + } + // plungers + using (var enumerator = PlungerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var plungerState = ref enumerator.Current.Value; + PlungerVelocityPhysics.UpdateVelocities(ref plungerState.Movement, ref plungerState.Velocity, in plungerState.Static); + } + } + // spinners + using (var enumerator = SpinnerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var spinnerState = ref enumerator.Current.Value; + SpinnerVelocityPhysics.UpdateVelocities(ref spinnerState.Movement, in spinnerState.Static); + } + } + + #endregion + + // primary physics loop + cycle.Simulate(ref state, physicsDiffTime, timeMsec); + + // ball trail, keep old pos of balls + using (var enumerator = state.Balls.GetEnumerator()) { + while (enumerator.MoveNext()) { + BallRingCounterPhysics.Update(ref enumerator.Current.Value); + } + } + + #region Animation + + // bumper + using (var enumerator = BumperStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var bumperState = ref enumerator.Current.Value; + if (bumperState.RingItemId != 0) { + BumperRingAnimation.Update(ref bumperState.RingAnimation, DeltaTimeMs); + } + if (bumperState.SkirtItemId != 0) { + BumperSkirtAnimation.Update(ref bumperState.SkirtAnimation, DeltaTimeMs); + } + } + } + + // drop target + using (var enumerator = DropTargetStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var dropTargetState = ref enumerator.Current.Value; + DropTargetAnimation.Update(enumerator.Current.Key, ref dropTargetState.Animation, in dropTargetState.Static, ref state, timeMsec); + } + } + + // hit target + using (var enumerator = HitTargetStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var hitTargetState = ref enumerator.Current.Value; + HitTargetAnimation.Update(ref hitTargetState.Animation, in hitTargetState.Static, timeMsec); + } + } + + // plunger + using (var enumerator = PlungerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var plungerState = ref enumerator.Current.Value; + PlungerAnimation.Update(ref plungerState.Animation, in plungerState.Movement, in plungerState.Static); + } + } + + // trigger + using (var enumerator = TriggerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var triggerState = ref enumerator.Current.Value; + TriggerAnimation.Update(ref triggerState.Animation, ref triggerState.Movement, in triggerState.Static, DeltaTimeMs); + } + } + + #endregion + + env.CurPhysicsFrameTime = env.NextPhysicsFrameTime; + env.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; + env.TimeMsec = timeMsec; + } + + PhysicsEnv[0] = env; + cycle.Dispose(); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs.meta new file mode 100644 index 000000000..2817b063a --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0b10767332f9444e84e5c9293196e58a +timeCreated: 1697223526 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs index 3e4981c3b..114c8d6d8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs @@ -14,11 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT; -using VisualPinballUnity; namespace VisualPinball.Unity { @@ -42,17 +39,9 @@ public bool IsCollidable protected readonly int ItemId; protected readonly TCollidableComponent ColliderComponent; - private protected EntityManager EntityManager; - private readonly SimulateCycleSystemGroup _simulateCycleSystemGroup; - protected CollidableApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { - if (World.DefaultGameObjectInjectionWorld != null) { - _simulateCycleSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); - } - EntityManager = World.DefaultGameObjectInjectionWorld != null ? World.DefaultGameObjectInjectionWorld.EntityManager : default; ItemId = go.GetInstanceID(); - ColliderComponent = go.GetComponent(); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index ff585319a..4e96b8cf8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -158,7 +158,7 @@ private void OnDrawGizmos() var colliderBlob = allocateColliderJob.BlobAsset[0]; allocateColliderJob.Dispose(); - var populateJob = new PopulatePhysicsJob { + var populateJob = new PhysicsPopulateJob { Colliders = colliderBlob, Octree = octree, }; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs index c52ba1891..f972d83cd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs @@ -112,6 +112,8 @@ public void RotateToStart() state.Solenoid.Value = false; } + internal ref FlipperState State => ref PhysicsEngine.FlipperState(ItemId); + internal float StartAngle { set { From a7ec7933e3f970bbfb17b6bc7f9d42ae8b03bf00 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 13 Oct 2023 21:36:43 +0200 Subject: [PATCH 087/159] jobs: Also ditch IDebugUI (we have an editor) --- .../Inspectors/PlayerInspector.cs | 2 - .../Game/Engine/DefaultGamelogicEngine.cs | 45 ++++----- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 31 +++++++ .../VisualPinball.Unity/Game/Player.cs | 24 +---- .../VisualPinball.Unity/Physics/DebugUI.meta | 8 -- .../Physics/DebugUI/DebugFlipperSlider.cs | 46 ---------- .../DebugUI/DebugFlipperSlider.cs.meta | 11 --- .../Physics/DebugUI/DebugFlipperState.cs | 34 ------- .../Physics/DebugUI/DebugFlipperState.cs.meta | 11 --- .../Physics/DebugUI/IDebugUI.cs | 92 ------------------- .../Physics/DebugUI/IDebugUI.cs.meta | 11 --- .../VPT/ColliderComponent.cs | 16 ++-- .../VPT/ICollidableComponent.cs | 2 - 13 files changed, 64 insertions(+), 269 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperSlider.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperSlider.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperState.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperState.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs index 90baee1c3..ee10bdc85 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs @@ -28,7 +28,6 @@ public class PlayerInspector : UnityEditor.Editor private string[] _physicsEngineNames; private int _physicsEngineIndex; - private IDebugUI[] _debugUIs; private string[] _debugUINames; private int _debugUIIndex; @@ -49,7 +48,6 @@ public override void OnInspectorGUI() if (player == null) { return; } - DrawEngineSelector("Debug UI", ref player.debugUiId, ref _debugUIs, ref _debugUINames, ref _debugUIIndex); if (_toggleDebug = EditorGUILayout.BeginFoldoutHeaderGroup(_toggleDebug, "Debug")) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Engine/DefaultGamelogicEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Engine/DefaultGamelogicEngine.cs index 6d237596e..d5c77df18 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Engine/DefaultGamelogicEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Engine/DefaultGamelogicEngine.cs @@ -74,7 +74,7 @@ public class DefaultGamelogicEngine : MonoBehaviour, IGamelogicEngine private const string SwMotorEnd = "s_motor_end"; public GamelogicEngineSwitch[] RequestedSwitches => _availableSwitches.ToArray(); - private readonly List _availableSwitches = new List { + private readonly List _availableSwitches = new() { new GamelogicEngineSwitch(SwLeftFlipper) { Description = "Left Flipper (Button)", InputActionHint = InputConstants.ActionLeftFlipper }, new GamelogicEngineSwitch(SwRightFlipper) { Description = "Right Flipper (Button)", InputActionHint = InputConstants.ActionRightFlipper }, new GamelogicEngineSwitch(SwTroughDrain) { Description = "Trough Drain", DeviceHint = "^Trough\\s*\\d?", DeviceItemHint = TroughComponent.EntrySwitchId }, @@ -102,7 +102,8 @@ public class DefaultGamelogicEngine : MonoBehaviour, IGamelogicEngine public DisplayConfig[] RequiredDisplays => new[] { new DisplayConfig(DisplayDmd, DmdWidth, DmdHeight) }; public GamelogicEngineCoil[] RequestedCoils => _availableCoils.ToArray(); - private readonly List _availableCoils = new List { + private readonly List _availableCoils = new() + { new GamelogicEngineCoil(CoilLeftFlipperMain) { Description = "Left Flipper (Main)", DeviceHint = "^(LeftFlipper|LFlipper|FlipperLeft|FlipperL)$", DeviceItemHint = FlipperComponent.MainCoilItem }, new GamelogicEngineCoil(CoilLeftFlipperHold) { Description = "Left Flipper (Hold)", DeviceHint = "^(LeftFlipper|LFlipper|FlipperLeft|FlipperL)$", DeviceItemHint = FlipperComponent.HoldCoilItem }, new GamelogicEngineCoil(CoilRightFlipperMain) { Description = "Right Flipper (Main)", DeviceHint = "^(RightFlipper|RFlipper|FlipperRight|FlipperR)$", DeviceItemHint = FlipperComponent.MainCoilItem }, @@ -113,8 +114,8 @@ public class DefaultGamelogicEngine : MonoBehaviour, IGamelogicEngine }; public GamelogicEngineWire[] AvailableWires { get; } = { - new GamelogicEngineWire(SwLeftFlipper, CoilLeftFlipperMain, DestinationType.Coil, "Left Flipper"), - new GamelogicEngineWire(SwRightFlipper, CoilRightFlipperMain, DestinationType.Coil, "Right Flipper"), + new(SwLeftFlipper, CoilLeftFlipperMain, DestinationType.Coil, "Left Flipper"), + new(SwRightFlipper, CoilRightFlipperMain, DestinationType.Coil, "Right Flipper"), }; private const string GiSlingshotRightLower = "gi_1"; @@ -137,23 +138,23 @@ public class DefaultGamelogicEngine : MonoBehaviour, IGamelogicEngine private const string LampRedBumper = "l_bumper"; public GamelogicEngineLamp[] RequestedLamps { get; } = { - new GamelogicEngineLamp(GiSlingshotRightLower) { Description = "Right Slingshot (lower)", DeviceHint = "gi1$" }, - new GamelogicEngineLamp(GiSlingshotRightUpper) { Description = "Right Slingshot (upper)", DeviceHint = "gi2$" }, - new GamelogicEngineLamp(GiSlingshotLeftLower) { Description = "Left Slingshot (lower)", DeviceHint = "gi3$" }, - new GamelogicEngineLamp(GiSlingshotLeftUpper) { Description = "Left Slingshot (upper)", DeviceHint = "gi4$" }, - new GamelogicEngineLamp(GiDropTargetsRightLower) { Description = "Right Drop Targets (lower)", DeviceHint = "gi5$" }, - new GamelogicEngineLamp(GiDropTargetsRightUpper) { Description = "Right Drop Targets (upper)", DeviceHint = "gi8$" }, - new GamelogicEngineLamp(GiDropTargetsLeftLower) { Description = "Left Drop Targets (lower)", DeviceHint = "gi6$" }, - new GamelogicEngineLamp(GiDropTargetsLeftUpper) { Description = "Left Drop Targets (upper)", DeviceHint = "gi7$" }, - new GamelogicEngineLamp(GiTop1) { Description = "Top 1 (left)", DeviceHint = "gi13$" }, - new GamelogicEngineLamp(GiTop2) { Description = "Top 2", DeviceHint = "gi10$" }, - new GamelogicEngineLamp(GiTop3) { Description = "Top 3", DeviceHint = "gi9$" }, - new GamelogicEngineLamp(GiTop4) { Description = "Top 4", DeviceHint = "gi11$" }, - new GamelogicEngineLamp(GiTop5) { Description = "Top 5 (right)", DeviceHint = "gi12$" }, - new GamelogicEngineLamp(GiLowerRamp) { Description = "Ramp (lower)", DeviceHint = "gi14$" }, - new GamelogicEngineLamp(GiUpperRamp) { Description = "Ramp (upper)", DeviceHint = "gi15$" }, - new GamelogicEngineLamp(GiTopLeftPlastic) { Description = "Top Left Plastics", DeviceHint = "gi16$" }, - new GamelogicEngineLamp(LampRedBumper) { Description = "Red Bumper", DeviceHint = "^b1l2$" } + new(GiSlingshotRightLower) { Description = "Right Slingshot (lower)", DeviceHint = "gi1$" }, + new(GiSlingshotRightUpper) { Description = "Right Slingshot (upper)", DeviceHint = "gi2$" }, + new(GiSlingshotLeftLower) { Description = "Left Slingshot (lower)", DeviceHint = "gi3$" }, + new(GiSlingshotLeftUpper) { Description = "Left Slingshot (upper)", DeviceHint = "gi4$" }, + new(GiDropTargetsRightLower) { Description = "Right Drop Targets (lower)", DeviceHint = "gi5$" }, + new(GiDropTargetsRightUpper) { Description = "Right Drop Targets (upper)", DeviceHint = "gi8$" }, + new(GiDropTargetsLeftLower) { Description = "Left Drop Targets (lower)", DeviceHint = "gi6$" }, + new(GiDropTargetsLeftUpper) { Description = "Left Drop Targets (upper)", DeviceHint = "gi7$" }, + new(GiTop1) { Description = "Top 1 (left)", DeviceHint = "gi13$" }, + new(GiTop2) { Description = "Top 2", DeviceHint = "gi10$" }, + new(GiTop3) { Description = "Top 3", DeviceHint = "gi9$" }, + new(GiTop4) { Description = "Top 4", DeviceHint = "gi11$" }, + new(GiTop5) { Description = "Top 5 (right)", DeviceHint = "gi12$" }, + new(GiLowerRamp) { Description = "Ramp (lower)", DeviceHint = "gi14$" }, + new(GiUpperRamp) { Description = "Ramp (upper)", DeviceHint = "gi15$" }, + new(GiTopLeftPlastic) { Description = "Top Left Plastics", DeviceHint = "gi16$" }, + new(LampRedBumper) { Description = "Red Bumper", DeviceHint = "^b1l2$" } }; private Player _player; @@ -162,7 +163,7 @@ public class DefaultGamelogicEngine : MonoBehaviour, IGamelogicEngine private PlayfieldComponent _playfieldComponent; private const float FlipperLag = 0.5f; - private readonly Dictionary _switchTime = new Dictionary(); + private readonly Dictionary _switchTime = new(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index ba16bfbab..1b2c6a439 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -61,6 +61,7 @@ public class PhysicsEngine : MonoBehaviour #endregion [NonSerialized] private readonly Queue _inputActions = new(); + [NonSerialized] private readonly List _scheduledActions = new(); [NonSerialized] private Player _player; @@ -68,6 +69,14 @@ public class PhysicsEngine : MonoBehaviour #region API + public void ScheduleAction(int timeoutMs, Action action) => ScheduleAction((uint)timeoutMs, action); + public void ScheduleAction(uint timeoutMs, Action action) + { + lock (_scheduledActions) { + _scheduledActions.Add(new ScheduledAction(_physicsEnv[0].CurPhysicsFrameTime + (ulong)timeoutMs * 1000, action)); + } + } + internal delegate void InputAction(ref PhysicsState state); internal void Schedule(InputAction action) => _inputActions.Enqueue(action); @@ -201,6 +210,16 @@ private void Update() _player.OnEvent(in eventData); } + // process scheduled events from managed land + lock (_scheduledActions) { + for (var i = _scheduledActions.Count - 1; i >= 0; i--) { + if (_physicsEnv[0].CurPhysicsFrameTime > _scheduledActions[i].ScheduleAt) { + _scheduledActions[i].Action(); + _scheduledActions.RemoveAt(i); + } + } + } + // retrieve updated data _ballStates = updatePhysics.Balls; _physicsEnv = updatePhysics.PhysicsEnv; @@ -332,5 +351,17 @@ private static BlobAssetReference AllocateColliders(ref ColliderRe } #endregion + + private class ScheduledAction + { + public readonly ulong ScheduleAt; + public readonly Action Action; + + public ScheduledAction(ulong scheduleAt, Action action) + { + ScheduleAt = scheduleAt; + Action = action; + } + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 85627f6e7..583ddc06c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -18,7 +18,6 @@ using System.Collections.Generic; using System.Linq; using NLog; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using UnityEngine.InputSystem; @@ -26,9 +25,8 @@ using VisualPinball.Engine.Game; using VisualPinball.Engine.Game.Engines; using VisualPinball.Engine.VPT.Trigger; -using VisualPinballUnity; -using Logger = NLog.Logger; using Color = VisualPinball.Engine.Math.Color; +using Logger = NLog.Logger; namespace VisualPinball.Unity { @@ -76,7 +74,6 @@ public class Player : MonoBehaviour // input related [NonSerialized] private InputManager _inputManager; - [NonSerialized] private VisualPinballSimulationSystemGroup _simulationSystemGroup; [NonSerialized] private readonly List<(InputAction, Action)> _actions = new(); // players @@ -94,8 +91,6 @@ public class Player : MonoBehaviour private PlayfieldComponent _playfieldComponent; private PhysicsEngine _physicsEngine; - internal static readonly Entity PlayfieldEntity = new() {Index = -3, Version = 0}; // a fake entity we just use for reference - #region Access internal IApiSwitch Switch(ISwitchDeviceComponent component, string switchItem) => component != null ? _switchPlayer.Switch(component, switchItem) : null; @@ -148,11 +143,6 @@ private void Awake() _wirePlayer.Awake(_tableComponent, _inputManager, _switchPlayer, this); _displayPlayer.Awake(GamelogicEngine); } - - if (!string.IsNullOrEmpty(debugUiId)) { - EngineProvider.Set(debugUiId); - } - _simulationSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); } private void Start() @@ -172,10 +162,6 @@ private void Start() _wirePlayer.OnStart(); GamelogicEngine?.OnInit(this, TableApi, BallManager); - - if (EngineProvider.Exists) { - EngineProvider.Get().Init(_tableComponent); - } } private void Update() @@ -213,9 +199,6 @@ public void RegisterBumper(BumperComponent component) public void RegisterFlipper(FlipperComponent component) { Register(new FlipperApi(component.gameObject, this, _physicsEngine), component); - if (EngineProvider.Exists) { - EngineProvider.Get().OnRegisterFlipper(component.GetInstanceID(), component.gameObject.name); - } } public void RegisterDropTarget(DropTargetComponent component) @@ -426,9 +409,8 @@ private void RegisterCollider(int itemId, IApiColliderGenerator apiColl) #region Events - public void Queue(Action action) => _simulationSystemGroup.QueueBeforeBallCreation(action); - public void ScheduleAction(int timeMs, Action action) => _simulationSystemGroup.ScheduleAction(timeMs, action); - public void ScheduleAction(uint timeMs, Action action) => _simulationSystemGroup.ScheduleAction(timeMs, action); + public void ScheduleAction(int timeMs, Action action) => _physicsEngine.ScheduleAction(timeMs, action); + public void ScheduleAction(uint timeMs, Action action) => _physicsEngine.ScheduleAction(timeMs, action); public void OnEvent(in EventData eventData) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI.meta deleted file mode 100644 index 44ca312b6..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8c8201e573a5b824fa8463da684c07b3 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperSlider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperSlider.cs deleted file mode 100644 index 6500ba6c7..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperSlider.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable MemberCanBePrivate.Global - -namespace VisualPinball.Unity -{ - public class DebugFlipperSlider - { - public readonly string Label; - public readonly DebugFlipperSliderParam Param; - public readonly float MinValue; - public readonly float MaxValue; - - public DebugFlipperSlider(string label, DebugFlipperSliderParam param, float minValue, float maxValue) - { - Label = label; - Param = param; - MinValue = minValue; - MaxValue = maxValue; - } - } - - public enum DebugFlipperSliderParam - { - Acc = 1, - OffScale = 2, - OnNearEndScale = 3, - NumOfDegreeNearEnd = 4, - Mass = 5, - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperSlider.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperSlider.cs.meta deleted file mode 100644 index 3f16f6823..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperSlider.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b27b24d96c69de14b8ed68eb4efabfd3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperState.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperState.cs deleted file mode 100644 index 1e0635ab5..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperState.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinball.Unity -{ - public struct DebugFlipperState - { - public Entity Entity; - public float Angle; - public bool Solenoid; - - public DebugFlipperState(Entity entity, float angle, bool solenoid) - { - Entity = entity; - Angle = angle; - Solenoid = solenoid; - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperState.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperState.cs.meta deleted file mode 100644 index dd4997f45..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/DebugFlipperState.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 26c795fe292cd8346a874c5b8947ca26 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs deleted file mode 100644 index e257adc5e..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using VisualPinball.Engine.Common; - -namespace VisualPinball.Unity -{ - public interface IDebugUI : IEngine - { - /// - /// Initializes the debug UI. This is called in the table's Start() method. - /// - /// Table component - void Init(TableComponent tableComponent); - - /// - /// Called when a physics cycle has completed. - /// - /// Physics simulation clock time in miliseconds - /// Number of completed ticks - /// Number of milliseconds of cpu time used for physics simulation - void OnPhysicsUpdate(double physicClockMilliseconds, int numSteps, float processingTimeMilliseconds); - - /// - /// Called when a flipper has been converted to an entity. - /// - /// Flipper entity - /// Name of the flipper - void OnRegisterFlipper(int itemId, string name); - - /// - /// Called when a new ball has been created. - /// - /// Ball entity - void OnCreateBall(Entity entity); - - /// - /// Add new property to debug window. - /// If type T is not recognized it is treated as beginning of new group. - /// - /// Data type, like Vector3, float, int, ... - /// index to parent. If =-1 it means root. - /// Label or name of group. - /// Initial value. - /// Message to display as tooltip. - /// Index of property. Use it as parentIdx or propIdx. - int AddProperty(int parentIdx, string name, T value, string tip = null); - - /// - /// Get property value from DebugUI. - /// - /// Data type, like Vector3, float, int, ... - /// - /// Output where new value will be writen. - /// true if value is changed. - bool GetProperty(int propIdx, ref T value); - - - /// - /// Set property value in DebugUI. - /// - /// Data type, like Vector3, float, int, ... - /// Index of property. - /// New value for property. - void SetProperty(int propIdx, T value); - - /// - /// One line to add property (to Quick group) and sync value. - /// Property is recognized base on name & type. So, you can use same name for different types - /// - /// Data type, like Vector3, float, int, ... - /// Label for property. - /// Current value as input. Can be updated. - /// Message to display as tooltip. - /// true if value is changed. - bool QuickPropertySync(string name, ref T value, string tip = null); - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs.meta deleted file mode 100644 index d6bd084f1..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/DebugUI/IDebugUI.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 178b946ad7cc63e4cbfe4f9866549ee8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index 4e96b8cf8..38a8d8841 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -20,10 +20,10 @@ using System.Collections.Generic; using System.Linq; using NativeTrees; -using Unity.Entities; -using Unity.Mathematics; using Unity.Collections; using Unity.Jobs; +using Unity.Mathematics; +using UnityEditor; using UnityEngine; using UnityEngine.Profiling; using VisualPinball.Engine.VPT; @@ -58,8 +58,6 @@ public abstract class ColliderComponent : SubComponent _collidersDirty = value; } - private readonly Entity _colliderEntity = Player.PlayfieldEntity; - [NonSerialized] private Mesh _colliderMesh; [NonSerialized] private readonly List _nonMeshColliders = new List(); [NonSerialized] private bool _collidersDirty; @@ -122,7 +120,7 @@ private void OnDrawGizmos() } var ltw = GetComponentInParent().transform.localToWorldMatrix; Gizmos.matrix = ltw * (Matrix4x4)Physics.VpxToWorld; - UnityEditor.Handles.matrix = Gizmos.matrix; + Handles.matrix = Gizmos.matrix; var generateColliders = ShowAabbs || showColliders && !HasCachedColliders; if (generateColliders) { @@ -171,7 +169,7 @@ private void OnDrawGizmos() if (showColliders) { var color = Color.green; - UnityEditor.Handles.color = color; + Handles.color = color; color.a = 0.3f; Gizmos.color = color; Gizmos.DrawMesh(_colliderMesh); @@ -183,7 +181,7 @@ private void OnDrawGizmos() } Gizmos.matrix = Matrix4x4.identity; - UnityEditor.Handles.matrix = Matrix4x4.identity; + Handles.matrix = Matrix4x4.identity; Profiler.EndSample(); } @@ -193,7 +191,7 @@ private void OnDrawGizmos() private Mesh GenerateColliderMesh(ref ColliderReference colliders) { var color = Color.green; - UnityEditor.Handles.color = color; + Handles.color = color; color.a = 0.3f; Gizmos.color = color; var vertices = new List(); @@ -313,7 +311,7 @@ private static void AddCollider(CircleCollider circleCol, IList vertice private static void DrawLine(Vector3 p1, Vector3 p2) { const int thickness = 10; - UnityEditor.Handles.DrawAAPolyLine(thickness, p1, p2); + Handles.DrawAAPolyLine(thickness, p1, p2); } private static void AddCollider(LineZCollider lineZCol, ICollection vertices, ICollection normals, ICollection indices) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs index 091f2a35d..1271ab284 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs @@ -14,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System.Collections.Generic; - namespace VisualPinball.Unity { public interface ICollidableComponent From b4fb8ecc97b1dea63b23c705413ff8b82599c756 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 13 Oct 2023 22:16:29 +0200 Subject: [PATCH 088/159] jobs: Ditch remaining bakers. --- .../VisualPinball.Unity/VPT/ItemBaker.cs | 31 --------- .../VisualPinball.Unity/VPT/ItemBaker.cs.meta | 3 - .../VPT/Kicker/KickerBaker.cs | 65 ------------------- .../VPT/Kicker/KickerBaker.cs.meta | 3 - .../VPT/MetalWireGuide/MetalWireGuideBaker.cs | 31 --------- .../MetalWireGuideBaker.cs.meta | 3 - .../VPT/Primitive/PrimitiveBaker.cs | 31 --------- .../VPT/Primitive/PrimitiveBaker.cs.meta | 3 - .../VisualPinball.Unity/VPT/Ramp/RampBaker.cs | 30 --------- .../VPT/Ramp/RampBaker.cs.meta | 3 - .../VPT/Rubber/RubberBaker.cs | 31 --------- .../VPT/Rubber/RubberBaker.cs.meta | 3 - 12 files changed, 237 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs deleted file mode 100644 index b61b40443..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using VisualPinball.Engine.VPT; - -namespace VisualPinball.Unity -{ - public abstract class ItemBaker : Baker - where T : MainRenderableComponent - where TData : ItemData - { - public override void Bake(T authoring) - { - authoring.Entity = GetEntity(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs.meta deleted file mode 100644 index 1589fc76d..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c70518a0b50849d7a4d5bfa6615ffa93 -timeCreated: 1673021439 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs deleted file mode 100644 index 4a0e2ef9e..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using VisualPinball.Engine.VPT.Kicker; - -namespace VisualPinball.Unity -{ - public class KickerBaker : ItemBaker - { - public override void Bake(KickerComponent authoring) - { - base.Bake(authoring); - - // collision - var colliderComponent = GetComponent(); - if (colliderComponent) { - AddComponent(new KickerStaticData { - Center = authoring.Position, - FallIn = colliderComponent.FallIn, - FallThrough = colliderComponent.FallThrough, - HitAccuracy = colliderComponent.HitAccuracy, - Scatter = colliderComponent.Scatter, - LegacyMode = true, // todo colliderComponent.LegacyMode, - ZLow = authoring.Surface?.Height(authoring.Position) ?? authoring.PlayfieldHeight - }); - - AddComponent(new KickerCollisionData()); - - // if (!Data.LegacyMode) { - // // todo currently we don't allow non-legacy mode - // using (var blobBuilder = new BlobBuilder(Allocator.Temp)) { - // ref var blobAsset = ref blobBuilder.ConstructRoot(); - // var vertices = blobBuilder.Allocate(ref blobAsset.Vertices, Item.KickerHit.HitMesh.Length); - // var normals = blobBuilder.Allocate(ref blobAsset.Normals, Item.KickerHit.HitMesh.Length); - // for (var i = 0; i < Item.KickerHit.HitMesh.Length; i++) { - // var v = Item.KickerHit.HitMesh[i]; - // vertices[i] = new KickerMeshVertex { Vertex = v.ToUnityFloat3() }; - // normals[i] = new KickerMeshVertex { Vertex = new float3(KickerHitMesh.Vertices[i].Nx, KickerHitMesh.Vertices[i].Ny, KickerHitMesh.Vertices[i].Nz) }; - // } - // - // var blobAssetReference = blobBuilder.CreateBlobAssetReference(Allocator.Persistent); - // dstManager.AddComponentData(entity, new ColliderMeshData { Value = blobAssetReference }); - // } - // } - } - - // register - GetComponentInParent().RegisterKicker(authoring); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs.meta deleted file mode 100644 index ecb64cac8..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: bc1c67453a004de8b0c4308582274ac5 -timeCreated: 1673023434 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs deleted file mode 100644 index 838a837e2..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using VisualPinball.Engine.VPT.MetalWireGuide; - -namespace VisualPinball.Unity -{ - public class MetalWireGuideBaker : ItemBaker - { - public override void Bake(MetalWireGuideComponent authoring) - { - base.Bake(authoring); - - // register - GetComponentInParent().RegisterMetalWireGuide(authoring); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs.meta deleted file mode 100644 index 3fd756b08..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c9015c8886cf41dab8a6dbc6d9603430 -timeCreated: 1673023719 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs deleted file mode 100644 index 76d2ed249..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using VisualPinball.Engine.VPT.Primitive; - -namespace VisualPinball.Unity -{ - public class PrimitiveBaker : ItemBaker - { - public override void Bake(PrimitiveComponent authoring) - { - base.Bake(authoring); - - // register - GetComponentInParent().RegisterPrimitive(authoring); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs.meta deleted file mode 100644 index 5ece714f5..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 5ce35e9d5b3c496090d2fc3d5fe22aac -timeCreated: 1673093011 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs deleted file mode 100644 index 5d12b8ba4..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using VisualPinball.Engine.VPT.Ramp; - -namespace VisualPinball.Unity -{ - public class RampBaker : ItemBaker - { - public override void Bake(RampComponent authoring) - { - base.Bake(authoring); - - GetComponentInParent().RegisterRamp(authoring); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs.meta deleted file mode 100644 index 3142c0c3d..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: bec725d2d4fd43f78b960e620ca4a5dc -timeCreated: 1673093175 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs deleted file mode 100644 index f6d7d9d2f..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using VisualPinball.Engine.VPT.Rubber; - -namespace VisualPinball.Unity -{ - public class RubberBaker : ItemBaker - { - public override void Bake(RubberComponent authoring) - { - base.Bake(authoring); - - // register - GetComponentInParent().RegisterRubber(authoring); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs.meta deleted file mode 100644 index 1aee0db8b..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberBaker.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f5648372dbe2451e83fb775213540e72 -timeCreated: 1673093311 \ No newline at end of file From 4398222201ac8f1620afe2728728115a0c38a86c Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 13 Oct 2023 22:22:22 +0200 Subject: [PATCH 089/159] jobs: Add missing registrations. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 12 +++--------- .../Game/PhysicsStaticCollision.cs | 3 ++- .../VisualPinball.Unity/Game/Player.cs | 9 +-------- .../VPT/Flipper/FlipperComponent.cs | 1 + .../VPT/MetalWireGuide/MetalWireGuideComponent.cs | 11 +++++++++++ .../VPT/Primitive/PrimitiveComponent.cs | 2 ++ .../VisualPinball.Unity/VPT/Ramp/RampComponent.cs | 11 +++++++++++ .../VPT/Rubber/RubberComponent.cs | 11 +++++++++++ 8 files changed, 42 insertions(+), 18 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 1b2c6a439..dea6602f5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -33,10 +33,10 @@ public class PhysicsEngine : MonoBehaviour #region States [NonSerialized] private InsideOfs _insideOfs; - [NonSerialized] private NativeArray _physicsEnv; [NonSerialized] private NativeOctree _octree; - [NonSerialized] private NativeQueue _eventQueue; [NonSerialized] private BlobAssetReference _colliders; + [NonSerialized] private NativeArray _physicsEnv = new(1, Allocator.Persistent); + [NonSerialized] private NativeQueue _eventQueue = new(Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _ballStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _bumperStates = new(0, Allocator.Persistent); @@ -121,13 +121,11 @@ private void Awake() { _player = GetComponent(); _insideOfs = new InsideOfs(Allocator.Persistent); + _physicsEnv[0] = new PhysicsEnv(NowUsec, GetComponent()); } private void Start() { - // init state - var env = new PhysicsEnv(NowUsec, GetComponent()); - // create static octree var sw = Stopwatch.StartNew(); var colliderItems = GetComponentsInChildren(); @@ -159,10 +157,6 @@ private void Start() foreach (var ball in balls) { Register(ball); } - - _eventQueue = new NativeQueue(Allocator.Persistent); - _physicsEnv = new NativeArray(1, Allocator.Persistent); - _physicsEnv[0] = env; } private void Update() diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 7f4229706..c83d2ad11 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -17,6 +17,7 @@ // ReSharper disable ConvertIfStatementToSwitchStatement using VisualPinball.Engine.VPT; +using VisualPinball.Unity.Collections; namespace VisualPinball.Unity { @@ -166,7 +167,7 @@ private static void TriggerCollide(ref BallData ball, ref PhysicsState state, in if (triggerState.FlipperCorrection.IsEnabled) { if (triggerState.Animation.UnHitEvent) { ref var flipperCorrectionBlob = ref triggerState.FlipperCorrection.Value.Value; - ref var fs = ref state.GetFlipperState(flipperCorrectionBlob.FlipperItemId); + ref var fs = ref state.FlipperStates.GetValueByRef(flipperCorrectionBlob.FlipperItemId); FlipperCorrection.OnBallLeaveFlipper(ref ball, ref flipperCorrectionBlob, in fs.Movement, in fs.Tricks, in fs.Static, timeMs); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 583ddc06c..153dc875f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -313,13 +313,6 @@ public void RegisterTrigger(TriggerComponent component) Register(new TriggerApi(component.gameObject, this, _physicsEngine), component); } - public void RegisterTrigger(TriggerData data, GameObject go) - { - var component = go.AddComponent(); - component.SetData(data); - Register(new TriggerApi(go, this, _physicsEngine), component); - } - public void RegisterTrough(TroughComponent component) { Register(new TroughApi(component.gameObject, this, _physicsEngine), component); @@ -418,7 +411,7 @@ public void OnEvent(in EventData eventData) switch (eventData.EventId) { case EventId.HitEventsHit: if (!_hittables.ContainsKey(eventData.ItemId)) { - Debug.LogError($"Cannot find item {eventData.ItemId} in hittables."); + Debug.LogError($"Cannot find {eventData.ItemId} in hittables."); } _hittables[eventData.ItemId].OnHit(eventData.BallId); break; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index 4c9651af0..94b5f6c7b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -718,6 +718,7 @@ private void SetupFlipperCorrection(FlipperColliderComponent colliderComponent) // need to explicitly register, since awake was called before the components were added. GetComponentInParent().Register(triggerComponent); + GetComponentInParent().RegisterTrigger(triggerComponent); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs index 8af72c31f..2082e2f83 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs @@ -88,6 +88,17 @@ public class MetalWireGuideComponent : MainRenderableComponent().RegisterMetalWireGuide(this); + GetComponentInParent().Register(this); + } + + #endregion + #region Transformation public override void OnPlayfieldHeightUpdated() => RebuildMeshes(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs index cf3ae5c28..5cf613cb1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs @@ -246,6 +246,8 @@ public override void CopyFromObject(GameObject go) private void Awake() { _originalRotateZ = ObjectRotation.z; + GetComponentInParent().RegisterPrimitive(this); + GetComponentInParent().Register(this); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs index 493d36133..f98039062 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs @@ -121,6 +121,17 @@ public class RampComponent : MainRenderableComponent, #endregion + #region Runtime + + private void Awake() + { + // register at player + GetComponentInParent().RegisterRamp(this); + GetComponentInParent().Register(this); + } + + #endregion + #region Transformation public float Height(Vector2 pos) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs index a2804c0e5..6fcc9f42e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs @@ -84,6 +84,17 @@ public class RubberComponent : MainRenderableComponent, #endregion + #region Runtime + + private void Awake() + { + // register at player + GetComponentInParent().RegisterRubber(this); + GetComponentInParent().Register(this); + } + + #endregion + #region Transformation public override void OnPlayfieldHeightUpdated() => RebuildMeshes(); From cb0e3f6d7c77ce095195805ab8fa206387ef1914 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 14 Oct 2023 13:33:59 +0200 Subject: [PATCH 090/159] jobs: Make collision toggelable. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 8 ++++++-- .../VisualPinball.Unity/Game/PhysicsState.cs | 11 ++++++++++- .../Game/PhysicsStaticNarrowPhase.cs | 3 +++ .../VisualPinball.Unity/Game/PhysicsUpdateJob.cs | 4 +++- .../VisualPinball.Unity/Game/Player.cs | 9 +-------- .../Physics/Collider/ColliderInfo.cs | 1 - .../Physics/Collision/ColliderHeader.cs | 2 -- .../VisualPinball.Unity/VPT/CollidableApi.cs | 3 +-- .../VisualPinball.Unity/VPT/ColliderComponent.cs | 4 +++- .../VisualPinball.Unity/VPT/ICollidableComponent.cs | 2 ++ .../VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs | 1 - .../VPT/Plunger/PlungerComponent.cs | 1 - 12 files changed, 29 insertions(+), 20 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index dea6602f5..7015b08cc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -49,7 +49,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeParallelHashMap _spinnerStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _surfaceStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _triggerStates = new(0, Allocator.Persistent); - [NonSerialized] private NativeParallelHashSet _nonCollidableItems = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashSet _disabledCollisionItems = new(0, Allocator.Persistent); #endregion @@ -132,6 +132,9 @@ private void Start() Debug.Log($"Found {colliderItems.Length} collidable items."); var colliders = new ColliderReference(Allocator.TempJob); foreach (var colliderItem in colliderItems) { + if (!colliderItem.IsCollidable) { + _disabledCollisionItems.Add(colliderItem.ItemId); + } colliderItem.GetColliders(_player, ref colliders, 0); } @@ -182,13 +185,14 @@ private void Update() SpinnerStates = _spinnerStates, SurfaceStates = _surfaceStates, TriggerStates = _triggerStates, + DisabledCollisionItems = _disabledCollisionItems, }; var env = _physicsEnv[0]; var state = new PhysicsState(ref env, ref _octree, ref _colliders, ref events, ref _insideOfs, ref _ballStates, ref _bumperStates, ref _dropTargetStates, ref _flipperStates, ref _gateStates, ref _hitTargetStates, ref _kickerStates, ref _plungerStates, ref _spinnerStates, - ref _surfaceStates, ref _triggerStates); + ref _surfaceStates, ref _triggerStates, ref _disabledCollisionItems); // process input while (_inputActions.Count > 0) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 6623f2932..21e574f05 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -40,6 +40,7 @@ internal struct PhysicsState internal NativeParallelHashMap SpinnerStates; internal NativeParallelHashMap SurfaceStates; internal NativeParallelHashMap TriggerStates; + internal NativeParallelHashSet DisabledCollisionItems; public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAssetReference colliders, ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeParallelHashMap balls, @@ -47,7 +48,8 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs ref NativeParallelHashMap flipperStates, ref NativeParallelHashMap gateStates, ref NativeParallelHashMap hitTargetStates, ref NativeParallelHashMap kickerStates, ref NativeParallelHashMap plungerStates, ref NativeParallelHashMap spinnerStates, - ref NativeParallelHashMap surfaceStates, ref NativeParallelHashMap triggerStates) + ref NativeParallelHashMap surfaceStates, ref NativeParallelHashMap triggerStates, + ref NativeParallelHashSet disabledCollisionItems) { Env = env; Octree = octree; @@ -65,10 +67,17 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs SpinnerStates = spinnerStates; SurfaceStates = surfaceStates; TriggerStates = triggerStates; + DisabledCollisionItems = disabledCollisionItems; } internal Collider GetCollider(int colliderId) => Colliders.Value.Colliders[colliderId].Value; + internal bool IsColliderActive(int colliderId) + { + var collider = GetCollider(colliderId); + return !DisabledCollisionItems.Contains(collider.ItemId); + } + #region States internal ref FlipperState GetFlipperState(int colliderId) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index bd1752af8..76216d31c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -34,6 +34,9 @@ ref PhysicsState state ball.CollisionEvent.ClearCollider(hitTime); // search upto current hit time for (var i = 0; i < overlappingColliders.Length; i++) { + if (!state.IsColliderActive(overlappingColliders[i])) { + continue; + } var newCollEvent = new CollisionEventData(); var newTime = state.HitTest(overlappingColliders[i], ref ball, ref newCollEvent, ref contacts, ref state); SaveCollisions(ref ball, ref newCollEvent, ref contacts, overlappingColliders[i], newTime); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs index 2517123c4..d160e2b81 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs @@ -48,6 +48,8 @@ internal struct PhysicsUpdateJob : IJob public NativeParallelHashMap SpinnerStates; public NativeParallelHashMap SurfaceStates; public NativeParallelHashMap TriggerStates; + public NativeParallelHashSet DisabledCollisionItems; + public void Execute() { @@ -55,7 +57,7 @@ public void Execute() var state = new PhysicsState(ref env, ref Octree, ref Colliders, ref Events, ref InsideOfs, ref Balls, ref BumperStates, ref DropTargetStates, ref FlipperStates, ref GateStates, ref HitTargetStates, ref KickerStates, ref PlungerStates, ref SpinnerStates, - ref SurfaceStates, ref TriggerStates); + ref SurfaceStates, ref TriggerStates, ref DisabledCollisionItems); var cycle = new PhysicsCycle(Allocator.Temp); while (env.CurPhysicsFrameTime < InitialTimeUsec) // loop here until current (real) time matches the physics (simulated) time diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 153dc875f..29ab4a31c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -328,6 +328,7 @@ private void Register(TApi api, MonoBehaviour component) where TApi : IApi TableApi.Register(component, api); _apis.Add(api); var itemId = component.gameObject.GetInstanceID(); + Debug.Log($"Registering {component.GetType()} {component.name} with ID {itemId}."); if (api is IApiRotatable rotatable) { _rotatables[itemId] = rotatable; } @@ -375,14 +376,6 @@ private void Register(TApi api, MonoBehaviour component) where TApi : IApi } } - private void RegisterTransform(Dictionary transforms, MonoBehaviour component) where T : MonoBehaviour - { - var comp = component.gameObject.GetComponentInChildren(); - if (comp) { - transforms[component.GetInstanceID()] = comp.gameObject.transform; - } - } - private void RegisterCollider(int itemId, IApiColliderGenerator apiColl) { if (!apiColl.IsColliderAvailable) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs index c9375bb23..bf860f531 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs @@ -34,6 +34,5 @@ public struct ColliderInfo public PhysicsMaterialData Material; public float HitThreshold; public bool FireEvents; - public bool IsEnabled; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs index dbd079b99..17192cf5a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs @@ -35,7 +35,6 @@ public struct ColliderHeader public float Threshold; public bool FireEvents; - public bool IsEnabled; /// /// Some colliders only collide with "primitives", which aren't only @@ -64,7 +63,6 @@ public void Init(ColliderInfo info, ColliderType colliderType) Material = info.Material; Threshold = info.HitThreshold; FireEvents = info.FireEvents; - IsEnabled = info.IsEnabled; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs index 114c8d6d8..9b572111a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs @@ -41,7 +41,7 @@ public bool IsCollidable protected CollidableApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base(go, player, physicsEngine) { - ItemId = go.GetInstanceID(); + ItemId = MainComponent.gameObject.GetInstanceID(); ColliderComponent = go.GetComponent(); } @@ -74,7 +74,6 @@ public ColliderInfo GetColliderInfo(ItemType itemType) ItemId = ItemId, ItemType = itemType, FireEvents = FireHitEvents, - IsEnabled = ColliderComponent && ColliderComponent.isActiveAndEnabled, Material = ColliderComponent.PhysicsMaterialData, HitThreshold = HitThreshold, }; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index 38a8d8841..28ff0541d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -432,7 +432,9 @@ void ICollidableComponent.GetColliders(Player player, ref ColliderReference coll { InstantiateColliderApi(player, null).CreateColliders(ref colliders, margin); } - #endif + int ICollidableComponent.ItemId => MainComponent.gameObject.GetInstanceID(); + bool ICollidableComponent.IsCollidable => isActiveAndEnabled; +#endif } internal static class ColliderColor diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs index 1271ab284..3367c18ea 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ICollidableComponent.cs @@ -19,5 +19,7 @@ namespace VisualPinball.Unity public interface ICollidableComponent { internal void GetColliders(Player player, ref ColliderReference colliders, float margin); + internal int ItemId { get; } + internal bool IsCollidable { get; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs index 1f969e87d..7684e480b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs @@ -39,7 +39,6 @@ protected override void CreateColliders(ref ColliderReference colliders, float m ItemId = ItemId, ItemType = ItemType.Table, FireEvents = false, - IsEnabled = true, Material = new PhysicsMaterialData { Elasticity = ColliderComponent.Elasticity, ElasticityFalloff = ColliderComponent.ElasticityFalloff, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs index ff3acb095..783f67ab0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs @@ -294,7 +294,6 @@ internal PlungerState CreateState() var info = new ColliderInfo { ItemId = GetInstanceID(), FireEvents = true, - IsEnabled = true, ItemType = ItemType.Plunger, }; From 4e7f6513818a0a509feb45190d166855bb720411 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 14 Oct 2023 20:57:40 +0200 Subject: [PATCH 091/159] jobs: Make collider toggle dynamic. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 12 ++++++++++++ .../VisualPinball.Unity/VPT/ColliderComponent.cs | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 7015b08cc..78dcaf0e2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -112,6 +112,18 @@ internal void Register(T item) where T : MonoBehaviour case TriggerComponent c: _triggerStates[itemId] = c.CreateState(); break; } } + internal void EnableCollider(int itemId) + { + if (_disabledCollisionItems.Contains(itemId)) { + _disabledCollisionItems.Remove(itemId); + } + } + internal void DisableCollider(int itemId) + { + if (!_disabledCollisionItems.Contains(itemId)) { + _disabledCollisionItems.Add(itemId); + } + } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index 28ff0541d..61d19c105 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -73,6 +73,16 @@ private void Start() // make enable checkbox visible } + private void OnEnable() + { + GetComponentInParent()?.EnableCollider(MainComponent.gameObject.GetInstanceID()); + } + + private void OnDisable() + { + GetComponentInParent()?.DisableCollider(MainComponent.gameObject.GetInstanceID()); + } + protected PhysicsMaterialData GetPhysicsMaterialData(float elasticity = 1f, float elasticityFalloff = 1f, float friction = 0f, float scatterAngleDeg = 0f, bool overwrite = true) { From f8cc5c94f2ab0a806cd9cdbd60f75c9fa383e9be Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 14 Oct 2023 21:43:05 +0200 Subject: [PATCH 092/159] jobs: Bump dependencies and remove remaining systems. --- .../VisualPinball.Unity.Editor.asmdef | 1 + .../VisualPinball.Unity/Game/DeviceSwitch.cs | 4 +- .../VisualPinball.Unity/Game/Player.cs | 15 +- .../VisualPinball.Unity/Game/SwitchHandler.cs | 14 +- .../VisualPinballSimulationSystemGroup.cs | 213 ------------------ ...VisualPinballSimulationSystemGroup.cs.meta | 11 - .../VisualPinball.Unity/Game/WirePlayer.cs | 16 +- .../Collision/DynamicBroadPhaseSystem.cs | 76 ------- .../Collision/DynamicBroadPhaseSystem.cs.meta | 11 - .../Collision/DynamicCollisionSystem.cs | 78 ------- .../Collision/DynamicCollisionSystem.cs.meta | 11 - .../Collision/DynamicNarrowPhaseSystem.cs | 87 ------- .../DynamicNarrowPhaseSystem.cs.meta | 11 - .../Physics/SystemGroup.meta | 8 - .../SystemGroup/SimulateBuildSystem.cs | 53 ----- .../SystemGroup/SimulateBuildSystem.cs.meta | 11 - .../SystemGroup/SimulateCycleSystemGroup.cs | 199 ---------------- .../SimulateCycleSystemGroup.cs.meta | 11 - .../VPT/CollisionSwitch/CollisionSwitchApi.cs | 5 +- .../VPT/DropTargetBank/DropTargetBankApi.cs | 7 +- .../VisualPinball.Unity/VPT/ItemApi.cs | 6 +- .../VPT/Mech/ScoreMotorApi.cs | 9 +- .../VPT/Mech/StepRotatorMechApi.cs | 8 +- .../VPT/Surface/SlingshotApi.cs | 5 +- .../VPT/Teleporter/TeleporterApi.cs | 9 +- package.json | 2 +- 26 files changed, 49 insertions(+), 832 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.asmdef b/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.asmdef index 04f6b9d53..f67a5a51e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.asmdef +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/VisualPinball.Unity.Editor.asmdef @@ -2,6 +2,7 @@ "name": "VisualPinball.Unity.Editor", "rootNamespace": "", "references": [ + "Unity.Collections", "Unity.Entities", "Unity.Entities.Hybrid", "Unity.Formats.Fbx.Editor", diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs index 3ede130b5..31e4e14e7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/DeviceSwitch.cs @@ -51,11 +51,11 @@ public class DeviceSwitch : IApiSwitch private readonly SwitchDefault _switchDefault; private readonly SwitchHandler _switchHandler; - public DeviceSwitch(string name, bool isPulseSwitch, SwitchDefault switchDefault, Player player) + public DeviceSwitch(string name, bool isPulseSwitch, SwitchDefault switchDefault, Player player, PhysicsEngine physicsEngine) { _isPulseSwitch = isPulseSwitch; _switchDefault = switchDefault; - _switchHandler = new SwitchHandler(name, player); + _switchHandler = new SwitchHandler(name, player, physicsEngine); } IApiSwitchStatus IApiSwitch.AddSwitchDest(SwitchConfig switchConfig, IApiSwitchStatus switchStatus) => diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 29ab4a31c..01b89ea42 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -24,7 +24,6 @@ using VisualPinball.Engine.Common; using VisualPinball.Engine.Game; using VisualPinball.Engine.Game.Engines; -using VisualPinball.Engine.VPT.Trigger; using Color = VisualPinball.Engine.Math.Color; using Logger = NLog.Logger; @@ -140,7 +139,7 @@ private void Awake() _lampPlayer.Awake(this, _tableComponent, GamelogicEngine); _coilPlayer.Awake(this, _tableComponent, GamelogicEngine, _lampPlayer, _wirePlayer); _switchPlayer.Awake(_tableComponent, GamelogicEngine, _inputManager); - _wirePlayer.Awake(_tableComponent, _inputManager, _switchPlayer, this); + _wirePlayer.Awake(_tableComponent, _inputManager, _switchPlayer, this, _physicsEngine); _displayPlayer.Awake(GamelogicEngine); } } @@ -238,27 +237,27 @@ public void RegisterLampGroup(LightGroupComponent component) public void RegisterStepRotator(StepRotatorMechComponent component) { - Register(new StepRotatorMechApi(component.gameObject, this), component); + Register(new StepRotatorMechApi(component.gameObject, this, _physicsEngine), component); } public void RegisterScoreMotorComponent(ScoreMotorComponent component) { - Register(new ScoreMotorApi(component.gameObject, this), component); + Register(new ScoreMotorApi(component.gameObject, this, _physicsEngine), component); } public void RegisterDropTargetBankComponent(DropTargetBankComponent component) { - Register(new DropTargetBankApi(component.gameObject, this), component); + Register(new DropTargetBankApi(component.gameObject, this, _physicsEngine), component); } public void RegisterCollisionSwitchComponent(CollisionSwitchComponent component) { - Register(new CollisionSwitchApi(component.gameObject, this), component); + Register(new CollisionSwitchApi(component.gameObject, this, _physicsEngine), component); } public void RegisterSlingshotComponent(SlingshotComponent component) { - Register(new SlingshotApi(component.gameObject, this), component); + Register(new SlingshotApi(component.gameObject, this, _physicsEngine), component); } public void RegisterPlunger(PlungerComponent component, InputActionReference actionRef) @@ -305,7 +304,7 @@ public void RegisterSurface(SurfaceComponent component) public void RegisterTeleporter(TeleporterComponent component) { - Register(new TeleporterApi(component.gameObject, this), component); + Register(new TeleporterApi(component.gameObject, this, _physicsEngine), component); } public void RegisterTrigger(TriggerComponent component) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs index 6c0f5e0ce..a616d237a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs @@ -45,6 +45,8 @@ public class SwitchHandler public readonly string Name; private readonly Player _player; + private readonly PhysicsEngine _physicsEngine; + private IGamelogicEngine Engine => _player.GamelogicEngine; /// @@ -59,13 +61,13 @@ public class SwitchHandler private readonly Dictionary _switchStatuses = new Dictionary(); - private static VisualPinballSimulationSystemGroup SimulationSystemGroup => World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - public SwitchHandler(string name, Player player, bool isEnabled = false) + public SwitchHandler(string name, Player player, PhysicsEngine physicsEngine, bool isEnabled = false) { Name = name; _player = player; + _physicsEngine = physicsEngine; IsEnabled = isEnabled; } @@ -130,7 +132,7 @@ internal void OnSwitch(bool enabled) // if it's pulse, schedule to re-open if (enabled && switchConfig.IsPulseSwitch) { - SimulationSystemGroup.ScheduleAction(switchConfig.PulseDelay, + _physicsEngine.ScheduleAction(switchConfig.PulseDelay, () => { _switchStatuses[switchConfig.SwitchId].IsSwitchEnabled = false; Engine.Switch(switchConfig.SwitchId, switchConfig.IsNormallyClosed); @@ -163,7 +165,7 @@ internal void ScheduleSwitch(bool enabled, int delay, Action onSwitched) // handle switch -> gamelogic engine if (Engine != null && _switches != null) { foreach (var switchConfig in _switches) { - SimulationSystemGroup.ScheduleAction(delay, + _physicsEngine.ScheduleAction(delay, () => Engine.Switch(switchConfig.SwitchId, switchConfig.IsNormallyClosed ? !enabled : enabled)); } } else { @@ -176,7 +178,7 @@ internal void ScheduleSwitch(bool enabled, int delay, Action onSwitched) var device = _player.WireDevice(wireConfig.Device); if (device != null) { var dest = device.Wire(wireConfig.DeviceItem); - SimulationSystemGroup.ScheduleAction(delay, () => dest.OnChange(enabled)); + _physicsEngine.ScheduleAction(delay, () => dest.OnChange(enabled)); } else { Logger.Warn($"Cannot find wire device \"{wireConfig.Device}\"."); @@ -185,7 +187,7 @@ internal void ScheduleSwitch(bool enabled, int delay, Action onSwitched) } // handle own status - SimulationSystemGroup.ScheduleAction(delay, () => { + _physicsEngine.ScheduleAction(delay, () => { Debug.Log($"Setting scheduled switch {Name} to {enabled}."); IsEnabled = enabled; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs deleted file mode 100644 index b325b1fb0..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs +++ /dev/null @@ -1,213 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using Unity.Entities; -using Unity.Transforms; -using VisualPinball.Engine.Common; - -namespace VisualPinballUnity -{ - /// - /// Main physics simulation system, executed once per frame. - /// - [UpdateBefore(typeof(TransformSystemGroup))] - internal partial class VisualPinballSimulationSystemGroup : ComponentSystemGroup - { - public double PhysicsDiffTime; - public double CurrentPhysicsTime => _currentPhysicsTime * (1.0 / PhysicsConstants.DefaultStepTime); - public uint TimeMsec; - - public override IReadOnlyList Systems => _systemsToUpdate; - - private readonly Stopwatch _time = new Stopwatch(); - private ulong _currentPhysicsTime; - private ulong _currentPhysicsFrameTime; - private ulong _nextPhysicsFrameTime; - - private readonly List _systemsToUpdate = new List(); - // private CreateBallEntityCommandBufferSystem _createBallEntityCommandBufferSystem; - // private UpdateVelocitiesSystemGroup _velocitiesSystemGroup; - // private SimulateCycleSystemGroup _simulateCycleSystemGroup; - // private BallRingCounterSystem _ballRingCounterSystem; - // private UpdateAnimationsSystemGroup _updateAnimationsSystemGroup; - // private TransformMeshesSystemGroup _transformMeshesSystemGroup; - - private readonly Queue _afterBallCreationQueue = new Queue(); - private readonly Queue _beforeBallCreationQueue = new Queue(); - private readonly List _scheduledActions = new List(); - - private const TimingMode Timing = TimingMode.UnityTime; - - protected override void OnCreate() - { - // let IPhysicsEngine enable it - Enabled = false; - - _time.Start(); - // - // _createBallEntityCommandBufferSystem = World.GetOrCreateSystemManaged(); - // _velocitiesSystemGroup = World.GetOrCreateSystemManaged(); - // _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - // todo re-enable system - // _ballRingCounterSystem = World.GetOrCreateSystemManaged(); - // _updateAnimationsSystemGroup = World.GetOrCreateSystemManaged(); - // _transformMeshesSystemGroup = World.GetOrCreateSystemManaged(); - - // _systemsToUpdate.Add(_createBallEntityCommandBufferSystem); - // _systemsToUpdate.Add(_velocitiesSystemGroup); - // _systemsToUpdate.Add(_simulateCycleSystemGroup); - // todo re-enable system - // _systemsToUpdate.Add(_ballRingCounterSystem); - // _systemsToUpdate.Add(_updateAnimationsSystemGroup); - // _systemsToUpdate.Add(_transformMeshesSystemGroup); - base.OnCreate(); - } - - protected override void OnStartRunning() - { - _currentPhysicsTime = GetTargetTime(); - _nextPhysicsFrameTime = _currentPhysicsTime + PhysicsConstants.PhysicsStepTime; - } - - protected override void OnUpdate() - { - lock (_beforeBallCreationQueue) { - while (_beforeBallCreationQueue.Count > 0) { - _beforeBallCreationQueue.Dequeue().Invoke(); - } - } - //_createBallEntityCommandBufferSystem.Update(); - lock (_afterBallCreationQueue) { - while (_afterBallCreationQueue.Count > 0) { - _afterBallCreationQueue.Dequeue().Invoke(); - } - } - - //const int startTimeUsec = 0; - var initialTimeUsec = GetTargetTime(); - - while (_currentPhysicsFrameTime < initialTimeUsec) { - - TimeMsec = (uint) (SystemAPI.Time.ElapsedTime * 1000); - PhysicsDiffTime = (_nextPhysicsFrameTime - _currentPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime); - - // update velocities - //_velocitiesSystemGroup.Update(); - - // simulate cycle - //_simulateCycleSystemGroup.Update(); - - // new cycle, on physics frame boundary - _currentPhysicsFrameTime = _nextPhysicsFrameTime; - - // advance physics position - _nextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; - - // run scheduled actions - lock (_scheduledActions) { - for (var i = _scheduledActions.Count - 1; i >= 0; i--) { - if (_currentPhysicsFrameTime > _scheduledActions[i].ScheduleAt) { - _scheduledActions[i].Action(); - _scheduledActions.RemoveAt(i); - } - } - } - } - - //_ballRingCounterSystem.Update(); - - _currentPhysicsTime = _currentPhysicsFrameTime; - - // update animations - //_updateAnimationsSystemGroup.Update(); - - // transform all meshes - //_transformMeshesSystemGroup.Update(); - } - - private ulong GetTargetTime() - { - const long dt60fps = 1000000 / 60; - - switch (Timing) { - case TimingMode.Atleast60: - var dt = (ulong)(SystemAPI.Time.DeltaTime * 1000000); - if (_currentPhysicsTime > 0 && dt > dt60fps) { - dt = dt60fps; - } - return _currentPhysicsTime + dt; - - case TimingMode.Locked60: - return _currentPhysicsTime + dt60fps; - - case TimingMode.UnityTime: - return (ulong)(SystemAPI.Time.ElapsedTime * 1000000); - - case TimingMode.SystemTime: - return (ulong) (_time.Elapsed.TotalMilliseconds * 1000); - - default: - throw new ArgumentOutOfRangeException(); - } - } - - public void QueueBeforeBallCreation(Action action) - { - lock (_beforeBallCreationQueue) { - _beforeBallCreationQueue.Enqueue(action); - } - } - - public void QueueAfterBallCreation(Action action) - { - lock (_afterBallCreationQueue) { - _afterBallCreationQueue.Enqueue(action); - } - } - - public void ScheduleAction(int timeoutMs, Action action) => ScheduleAction((uint)timeoutMs, action); - public void ScheduleAction(uint timeoutMs, Action action) - { - lock (_scheduledActions) { - _scheduledActions.Add(new ScheduledAction(_currentPhysicsFrameTime + (ulong)timeoutMs * 1000, action)); - } - } - - private enum TimingMode - { - UnityTime, - SystemTime, - Atleast60, - Locked60 - } - - private class ScheduledAction - { - public readonly ulong ScheduleAt; - public readonly Action Action; - - public ScheduledAction(ulong scheduleAt, Action action) - { - ScheduleAt = scheduleAt; - Action = action; - } - } - } - -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs.meta deleted file mode 100644 index 0a7ad6668..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballSimulationSystemGroup.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 86917f35ffc397f40852201b8deb1f07 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs index 1ef796fd3..4610cc571 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/WirePlayer.cs @@ -17,13 +17,10 @@ using System; using System.Collections.Generic; using System.Linq; -using Unity.Entities; +using NLog; using UnityEngine; using UnityEngine.InputSystem; -using NLog; -using VisualPinballUnity; using Logger = NLog.Logger; - #if UNITY_EDITOR using UnityEditor; #endif @@ -42,11 +39,11 @@ public class WirePlayer private readonly Dictionary>> _gleSignals = new Dictionary>>(); private Player _player; + private PhysicsEngine _physicsEngine; private TableComponent _tableComponent; private InputManager _inputManager; private SwitchPlayer _switchPlayer; - private static VisualPinballSimulationSystemGroup SimulationSystemGroup => World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); internal Dictionary WireStatuses { get; } = new Dictionary(); @@ -55,12 +52,13 @@ public class WirePlayer #region Lifecycle - public void Awake(TableComponent tableComponent, InputManager inputManager, SwitchPlayer switchPlayer, Player player) + public void Awake(TableComponent tableComponent, InputManager inputManager, SwitchPlayer switchPlayer, Player player, PhysicsEngine physicsEngine) { _tableComponent = tableComponent; _inputManager = inputManager; _switchPlayer = switchPlayer; _player = player; + _physicsEngine = physicsEngine; } public void OnStart() @@ -312,7 +310,7 @@ public void HandleSwitchChange(WireDestConfig wireConfig, bool isEnabled) // if it's pulse, schedule to re-open if (isEnabled && wireConfig.IsPulseSource) { - SimulationSystemGroup.ScheduleAction(wireConfig.PulseDelay, () => { + _physicsEngine.ScheduleAction(wireConfig.PulseDelay, () => { wire.OnChange(false); WireStatuses[wireConfig.Id] = (false, 0); #if UNITY_EDITOR @@ -330,7 +328,7 @@ public void HandleSwitchChange(WireDestConfig wireConfig, bool isEnabled) // if it's pulse, schedule to re-open if (isEnabled && wireConfig.IsPulseSource) { - SimulationSystemGroup.ScheduleAction(wireConfig.PulseDelay, () => { + _physicsEngine.ScheduleAction(wireConfig.PulseDelay, () => { wire.OnChange(false); WireStatuses[wireConfig.Id] = (false, -2); #if UNITY_EDITOR @@ -517,7 +515,7 @@ public class WireDestConfig internal bool IsActive; /// - /// Status flag for dynamic wires. Timestamp () + /// Status flag for dynamic wires. Timestamp () /// when the wire became active. /// internal float ActiveSince; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs deleted file mode 100644 index 3977ad3d3..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Collections; -using Unity.Entities; -using Unity.Profiling; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal partial class DynamicBroadPhaseSystem : SystemBaseStub - { - private EntityQuery _ballQuery; - private static readonly ProfilerMarker PerfMarker1 = new ProfilerMarker("DynamicBroadPhaseSystem.CreateKdTree"); - private static readonly ProfilerMarker PerfMarker2 = new ProfilerMarker("DynamicBroadPhaseSystem.GetAabbOverlaps"); - - protected override void OnCreate() { - _ballQuery = GetEntityQuery(ComponentType.ReadOnly()); - } - - protected override void OnUpdate() - { - // create kdtree - PerfMarker1.Begin(); - - var ballBounds = new NativeArray(_ballQuery.CalculateEntityCount(), Allocator.TempJob); - Entities.ForEach((Entity ballEntity, int entityInQueryIndex, in BallData ballData) => { - ballBounds[entityInQueryIndex] = ballData.Bounds(ballEntity); - }).Run(); - - var kdRoot = new KdRoot(); - Job.WithCode(() => kdRoot.Init(ballBounds, Allocator.TempJob)).Run(); - - PerfMarker1.End(); - - var overlappingEntities = GetBufferLookup(); - var marker = PerfMarker2; - - Entities - .WithName("DynamicBroadPhaseJob") - .WithDisposeOnCompletion(kdRoot) - .WithNativeDisableParallelForRestriction(overlappingEntities) - .ForEach((Entity entity, in BallData ball) => { - - // don't play with frozen balls - if (ball.IsFrozen) { - return; - } - - marker.Begin(); - - var colliderEntities = overlappingEntities[entity]; - colliderEntities.Clear(); - kdRoot.GetAabbOverlaps(in entity, in ball, ref colliderEntities); - - marker.End(); - - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs.meta deleted file mode 100644 index d35922185..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicBroadPhaseSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7de2d86b279848e458b629bbb2918e6d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs deleted file mode 100644 index 9a67d232f..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Profiling; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal partial class DynamicCollisionSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("DynamicCollisionSystem"); - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - - protected override void OnCreate() - { - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - } - - protected override void OnUpdate() - { - var marker = PerfMarker; - var hitTime = _simulateCycleSystemGroup.HitTime; - var swapBallCollisionHandling = _simulateCycleSystemGroup.SwapBallCollisionHandling; - var balls = GetComponentLookup(); - var collEvents = GetComponentLookup(true); - - // fixme job - // Entities - // .WithName("DynamicCollisionJob") - // .WithNativeDisableParallelForRestriction(balls) - // .WithReadOnly(collEvents) - // .ForEach((ref BallData ball, ref CollisionEventData collEvent) => { - // - // - // // pick "other" ball - // ref var otherId = ref collEvent.BallId; - // - // // find balls with hit objects and minimum time - // if (otherId != 0 && collEvent.HitTime <= hitTime) { - // - // marker.Begin(); - // - // var otherBall = balls[otherId]; - // var otherCollEvent = collEvents[otherId]; - // - // // now collision, contact and script reactions on active ball (object)+++++++++ - // - // //this.activeBall = ball; // For script that wants the ball doing the collision - // - // if (BallCollider.Collide(ref otherBall, ref ball,in otherCollEvent, in collEvent, swapBallCollisionHandling)) { - // balls[otherId] = otherBall; - // } - // - // // remove trial hit object pointer - // collEvent.ClearCollider(); - // - // marker.End(); - // } - // }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs.meta deleted file mode 100644 index 1aa341fe7..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicCollisionSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cf4c222b51824c44f989b0574936ed75 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs deleted file mode 100644 index 9cb9e6af7..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Profiling; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - [DisableAutoCreation] - internal partial class DynamicNarrowPhaseSystem : SystemBaseStub - { - private static readonly ProfilerMarker PerfMarker = new ProfilerMarker("DynamicNarrowPhaseSystem"); - private SimulateCycleSystemGroup _simulateCycleSystemGroup; - - protected override void OnCreate() - { - _simulateCycleSystemGroup = World.GetOrCreateSystemManaged(); - } - - protected override void OnUpdate() - { - var ballsLookup = GetComponentLookup(); - var contacts = _simulateCycleSystemGroup.Contacts; - - var marker = PerfMarker; - - // fixme job - // Entities - // .WithName("DynamicNarrowPhaseJob") - // .WithReadOnly(contacts) - // .WithNativeDisableParallelForRestriction(ballsLookup) - // .ForEach((Entity ballEntity, ref BallData ball, ref CollisionEventData collEvent, - // in DynamicBuffer overlappingEntities) => - // { - // // don't play with frozen balls - // if (ball.IsFrozen) { - // return; - // } - // - // marker.Begin(); - // - // //var contacts = contactsLookup[collDataEntity]; - // for (var k = 0; k < overlappingEntities.Length; k++) { - // var collBallEntity = overlappingEntities[k].Value; - // var collBall = ballsLookup[collBallEntity]; - // - // var newCollEvent = new CollisionEventData(); - // var newTime = BallCollider.HitTest(ref newCollEvent, ref ball, in collBall, collEvent.HitTime); - // var validHit = newTime >= 0 && !Math.Sign(newTime) && newTime <= collEvent.HitTime; - // - // if (newCollEvent.IsContact || validHit) { - // newCollEvent.SetCollider(collBallEntity); - // newCollEvent.HitTime = newTime; - // if (newCollEvent.IsContact) { - // contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); - // - // } else { // if (validhit) - // collEvent = newCollEvent; - // } - // } - // - // // write back - // ballsLookup[collBallEntity] = collBall; - // } - // - // marker.End(); - // - // } - // ).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs.meta deleted file mode 100644 index 17d2a5bb8..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/DynamicNarrowPhaseSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 78cc21e0c4cdaac48870177ec4b4fd99 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup.meta deleted file mode 100644 index 2d962cda5..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 81bce842dfe81a848a288463be2334ed -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs deleted file mode 100644 index 3695731b2..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2021 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; -using Unity.Transforms; -using UnityEngine; -using VisualPinball.Unity; -using VisualPinball.Unity.VisualPinball.Unity.Game; - -namespace VisualPinballUnity -{ - internal partial class SimulateBuildSystem : SystemBaseStub - { - private float4x4 _baseTransform; - - protected override void OnStartRunning() - { - var root = Object.FindObjectOfType(); - var ltw = root.gameObject.transform.localToWorldMatrix; - _baseTransform = new float4x4( - ltw.m00, ltw.m01, ltw.m02, ltw.m03, - ltw.m10, ltw.m11, ltw.m12, ltw.m13, - ltw.m20, ltw.m21, ltw.m22, ltw.m23, - ltw.m30, ltw.m31, ltw.m32, ltw.m33 - ); - } - - protected override void OnUpdate() - { - if (Application.isEditor) { - return; - } - var ltw = _baseTransform; - Entities.WithName("SimulateBuildJob").ForEach((ref BallData ball) => { - ball.Position = math.transform(math.inverse(ltw), math.transform(ltw, float3.zero)); - }).Run(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs.meta deleted file mode 100644 index dcceef4eb..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateBuildSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 35e8e832242528f40b7d4319a1e0db98 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs deleted file mode 100644 index 965af8223..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs +++ /dev/null @@ -1,199 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System.Collections.Generic; -using System.Diagnostics; -using Unity.Collections; -using Unity.Entities; -using UnityEngine; -using VisualPinball.Engine.Common; -using VisualPinball.Unity; - -namespace VisualPinballUnity -{ - /// - /// The main simulation loop - /// - [DisableAutoCreation] - internal partial class SimulateCycleSystemGroup : ComponentSystemGroup - { - /// - /// Time of the next collision; other systems can update this. - /// - public float HitTime; - - /// - /// Ball-ball collision resolution order is swapped each time - /// - public bool SwapBallCollisionHandling; - - public NativeHashMap ItemsColliding; - - public override IReadOnlyList Systems => _systemsToUpdate; - public NativeList Contacts; - - private readonly List _systemsToUpdate = new List(); - - //private StaticBroadPhaseSystem _staticBroadPhaseSystem; - private DynamicBroadPhaseSystem _dynamicBroadPhaseSystem; - //private StaticNarrowPhaseSystem _staticNarrowPhaseSystem; - private DynamicNarrowPhaseSystem _dynamicNarrowPhaseSystem; - //private UpdateDisplacementSystemGroup _displacementSystemGroup; - //private StaticCollisionSystem _staticCollisionSystem; - private DynamicCollisionSystem _dynamicCollisionSystem; - //private ContactSystem _contactSystem; - //private BallSpinHackPhysics _ballSpinHackPhysics; - - private float _staticCounts; - private EntityQuery _flipperDataQuery; - private EntityQuery _collisionEventDataQuery; - - private readonly Stopwatch _simulationTime = new Stopwatch(); - private VisualPinballSimulationSystemGroup _simulationSystemGroup; - - protected override void OnStartRunning() - { - base.OnStartRunning(); - QuadTreeCreator.Create(EntityManager, out ItemsColliding); - } - - protected override void OnCreate() - { - _flipperDataQuery = EntityManager.CreateEntityQuery(ComponentType.ReadOnly(), ComponentType.ReadOnly()); - _collisionEventDataQuery = EntityManager.CreateEntityQuery(ComponentType.ReadOnly()); - - // todo re-enable systems - // _simulationSystemGroup = World.GetExistingSystemManaged(); - // _staticBroadPhaseSystem = World.GetExistingSystemManaged(); - // _dynamicBroadPhaseSystem = World.GetExistingSystemManaged(); - // _staticNarrowPhaseSystem = World.GetExistingSystemManaged(); - // _dynamicNarrowPhaseSystem = World.GetExistingSystemManaged(); - // _displacementSystemGroup = World.GetExistingSystemManaged(); - // _staticCollisionSystem = World.GetExistingSystemManaged(); - // _dynamicCollisionSystem = World.GetExistingSystemManaged(); - // _contactSystem = World.GetExistingSystemManaged(); - // _ballSpinHackSystem = World.GetExistingSystemManaged(); - // _systemsToUpdate.Add(_staticBroadPhaseSystem); - // _systemsToUpdate.Add(_dynamicBroadPhaseSystem); - // _systemsToUpdate.Add(_staticNarrowPhaseSystem); - // _systemsToUpdate.Add(_dynamicNarrowPhaseSystem); - // _systemsToUpdate.Add(_displacementSystemGroup); - // _systemsToUpdate.Add(_staticCollisionSystem); - // _systemsToUpdate.Add(_dynamicCollisionSystem); - // _systemsToUpdate.Add(_contactSystem); - // _systemsToUpdate.Add(_ballSpinHackSystem); - - Contacts = new NativeList(Allocator.Persistent); - } - - protected override void OnDestroy() - { - // Contacts.Dispose(); - // ItemsColliding.Dispose(); - } - - protected override void OnUpdate() - { - if (Application.isEditor) { - UpdateCycle(); - - } else { - #if DEV_MODE_ENABLED - UpdateCycle(); - #endif - } - } - - private void UpdateCycle() - { - _simulationTime.Restart(); - - _staticCounts = PhysicsConstants.StaticCnts; - var dTime = _simulationSystemGroup.PhysicsDiffTime; - var numSteps = 0; - while (dTime > 0) { - - HitTime = (float)dTime; - - ApplyFlipperTime(); - ClearContacts(); - - _dynamicBroadPhaseSystem.Update(); - // _staticBroadPhaseSystem.Update(); - // _staticNarrowPhaseSystem.Update(); - _dynamicNarrowPhaseSystem.Update(); - - ApplyStaticTime(); - - //_displacementSystemGroup.Update(); - _dynamicCollisionSystem.Update(); - //_staticCollisionSystem.Update(); - //_contactSystem.Update(); - - ClearContacts(); - - //_ballSpinHackPhysics.Update(); - - dTime -= HitTime; - - SwapBallCollisionHandling = !SwapBallCollisionHandling; - ++numSteps; - } - } - - private void ClearContacts() - { - Contacts.Clear(); - } - - private void ApplyFlipperTime() - { - // for each flipper - var entities = _flipperDataQuery.ToEntityArray(Allocator.TempJob); - foreach (var entity in entities) { - var movementData = EntityManager.GetComponentData(entity); - var staticData = EntityManager.GetComponentData(entity); - var tricksData = EntityManager.GetComponentData(entity); - var flipperHitTime = movementData.GetHitTime(staticData.AngleStart, tricksData.AngleEnd); - - // if flipper comes to a rest before the end of the cycle, advance to that time - if (flipperHitTime > 0 && flipperHitTime < HitTime) { //!! >= 0.f causes infinite loop - HitTime = flipperHitTime; - } - } - entities.Dispose(); - } - - private void ApplyStaticTime() - { - // for each collision event - var entities = _collisionEventDataQuery.ToEntityArray(Allocator.TempJob); - foreach (var entity in entities) { - var collEvent = EntityManager.GetComponentData(entity); - if (collEvent.HasCollider() && collEvent.HitTime <= HitTime) { // smaller hit time?? - HitTime = collEvent.HitTime; // record actual event time - if (collEvent.HitTime < PhysicsConstants.StaticTime) { // less than static time interval - if (--_staticCounts < 0) { - _staticCounts = 0; // keep from wrapping - HitTime = PhysicsConstants.StaticTime; - } - } - } - } - entities.Dispose(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs.meta deleted file mode 100644 index ba3666d5e..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/SystemGroup/SimulateCycleSystemGroup.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3a0c324e97594e34caf2813cdf7b7eb5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs index dc2d8de83..5ef223522 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchApi.cs @@ -43,12 +43,12 @@ public class CollisionSwitchApi : IApi, IApiSwitch, IApiSwitchDevice public bool IsHittable => _hittable != null; - internal CollisionSwitchApi(GameObject go, Player player) + internal CollisionSwitchApi(GameObject go, Player player, PhysicsEngine physicsEngine) { _collisionSwitchComponent = go.GetComponentInChildren(); _player = player; - _switchHandler = new SwitchHandler(go.name, player); + _switchHandler = new SwitchHandler(go.name, player, physicsEngine); } void IApi.OnInit(BallManager ballManager) @@ -81,4 +81,3 @@ void IApi.OnDestroy() } } } - diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/DropTargetBank/DropTargetBankApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/DropTargetBank/DropTargetBankApi.cs index e01a7c1ee..498b264db 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/DropTargetBank/DropTargetBankApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/DropTargetBank/DropTargetBankApi.cs @@ -28,6 +28,7 @@ public class DropTargetBankApi : IApi, IApiCoilDevice, IApiSwitchDevice private readonly DropTargetBankComponent _dropTargetBankComponent; private readonly Player _player; + private readonly PhysicsEngine _physicsEngine; private readonly List _dropTargetApis = new List(); public DeviceSwitch SequenceCompletedSwitch; @@ -56,15 +57,16 @@ private IApiCoil Coil(string deviceItem) }; } - internal DropTargetBankApi(GameObject go, Player player) + internal DropTargetBankApi(GameObject go, Player player, PhysicsEngine physicsEngine) { _dropTargetBankComponent = go.GetComponentInChildren(); _player = player; + _physicsEngine = physicsEngine; } void IApi.OnInit(BallManager ballManager) { - SequenceCompletedSwitch = new DeviceSwitch(DropTargetBankComponent.SequenceCompletedSwitchItem, false, SwitchDefault.NormallyOpen, _player); + SequenceCompletedSwitch = new DeviceSwitch(DropTargetBankComponent.SequenceCompletedSwitchItem, false, SwitchDefault.NormallyOpen, _player, _physicsEngine); ResetCoil = new DeviceCoil(_player, OnResetCoilEnabled); for (var index = 0; index < _dropTargetBankComponent.BankSize; index++) { @@ -112,4 +114,3 @@ void IApi.OnDestroy() } } } - diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs index c2b07fef0..83569970f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemApi.cs @@ -14,10 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT; -using VisualPinballUnity; namespace VisualPinball.Unity { @@ -53,7 +51,7 @@ protected ItemApi(GameObject go, Player player, PhysicsEngine physicsEngine) GameObject = go; MainComponent = go.GetComponent(); Player = player; - SwitchHandler = new SwitchHandler(Name, player); + SwitchHandler = new SwitchHandler(Name, player, physicsEngine); PhysicsEngine = physicsEngine; } @@ -65,7 +63,7 @@ protected void OnInit(BallManager ballManager) #region IApiSwitchable - private protected DeviceSwitch CreateSwitch(string name, bool isPulseSwitch, SwitchDefault switchDefault = SwitchDefault.Configurable) => new DeviceSwitch(name, isPulseSwitch, switchDefault, Player); + private protected DeviceSwitch CreateSwitch(string name, bool isPulseSwitch, SwitchDefault switchDefault = SwitchDefault.Configurable) => new DeviceSwitch(name, isPulseSwitch, switchDefault, Player, PhysicsEngine); private protected IApiSwitchStatus AddSwitchDest(SwitchConfig switchConfig,IApiSwitchStatus switchStatus) => SwitchHandler.AddSwitchDest(switchConfig, switchStatus); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/ScoreMotorApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/ScoreMotorApi.cs index df699cfa5..dceb394d8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/ScoreMotorApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/ScoreMotorApi.cs @@ -27,6 +27,7 @@ public class ScoreMotorApi : IApi, IApiSwitchDevice private readonly ScoreMotorComponent _scoreMotorComponent; private readonly Player _player; + private readonly PhysicsEngine _physicsEngine; public event EventHandler Init; @@ -47,18 +48,19 @@ public IApiSwitch Switch(string deviceItem) }; } - internal ScoreMotorApi(GameObject go, Player player) + internal ScoreMotorApi(GameObject go, Player player, PhysicsEngine physicsEngine) { _scoreMotorComponent = go.GetComponentInChildren(); _player = player; + _physicsEngine = physicsEngine; _scoreMotorComponent.OnSwitchChanged += HandleSwitchChanged; } void IApi.OnInit(BallManager ballManager) { - _motorRunningSwitch = new DeviceSwitch(ScoreMotorComponent.MotorRunningSwitchItem, false, SwitchDefault.NormallyOpen, _player); - _motorStepSwitch = new DeviceSwitch(ScoreMotorComponent.MotorStepSwitchItem, true, SwitchDefault.NormallyOpen, _player); + _motorRunningSwitch = new DeviceSwitch(ScoreMotorComponent.MotorRunningSwitchItem, false, SwitchDefault.NormallyOpen, _player, _physicsEngine); + _motorStepSwitch = new DeviceSwitch(ScoreMotorComponent.MotorStepSwitchItem, true, SwitchDefault.NormallyOpen, _player, _physicsEngine); Init?.Invoke(this, EventArgs.Empty); } @@ -76,4 +78,3 @@ void IApi.OnDestroy() } } } - diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/StepRotatorMechApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/StepRotatorMechApi.cs index 2963a8013..473576ca7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/StepRotatorMechApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/StepRotatorMechApi.cs @@ -36,6 +36,7 @@ private enum Direction } private readonly Player _player; + private readonly PhysicsEngine _physicsEngine; private readonly StepRotatorMechComponent _component; private DeviceCoil _motorCoil; @@ -46,13 +47,13 @@ private enum Direction private Dictionary _switches; private Dictionary _marks; - internal StepRotatorMechApi(GameObject go, Player player) + internal StepRotatorMechApi(GameObject go, Player player, PhysicsEngine physicsEngine) { _component = go.GetComponentInChildren(); _player = player; + _physicsEngine = physicsEngine; } - void IApi.OnInit(BallManager ballManager) { _enabled = false; @@ -62,7 +63,7 @@ void IApi.OnInit(BallManager ballManager) _motorCoil = new DeviceCoil(_player, OnMotorCoilEnabled, OnMotorCoilDisabled); _marks = _component.Marks.ToDictionary(m => m.SwitchId, m => m); - _switches = _component.Marks.ToDictionary(m => m.SwitchId, m => new DeviceSwitch(m.SwitchId, false, SwitchDefault.NormallyOpen, _player)); + _switches = _component.Marks.ToDictionary(m => m.SwitchId, m => new DeviceSwitch(m.SwitchId, false, SwitchDefault.NormallyOpen, _player, _physicsEngine)); var i = 0; foreach (var sw in _switches.Values) { sw.SetSwitch(i == 0); @@ -161,4 +162,3 @@ void IApi.OnDestroy() } } } - diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs index 4caf0c53b..8e0699218 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotApi.cs @@ -42,12 +42,12 @@ public class SlingshotApi : IApi, IApiSwitch, IApiSwitchDevice private void OnSwitch(bool closed) => _switchHandler.OnSwitch(closed); - internal SlingshotApi(GameObject go, Player player) + internal SlingshotApi(GameObject go, Player player, PhysicsEngine physicsEngine) { _slingshotComponent = go.GetComponentInChildren(); _player = player; - _switchHandler = new SwitchHandler(go.name, player); + _switchHandler = new SwitchHandler(go.name, player, physicsEngine); } void IApi.OnInit(BallManager ballManager) @@ -77,4 +77,3 @@ void IApi.OnDestroy() } } } - diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs index a456d1b4c..43a3464f2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs @@ -32,19 +32,19 @@ public class TeleporterApi : IApi, IApiCoilDevice private readonly TeleporterComponent _component; private readonly Player _player; + private readonly PhysicsEngine _physicsEngine; private DeviceCoil _teleporterCoil; private KickerApi _fromKicker; private KickerApi _toKicker; - private readonly VisualPinballSimulationSystemGroup _simulationSystemGroup; public event EventHandler Init; - internal TeleporterApi(GameObject go, Player player) + internal TeleporterApi(GameObject go, Player player, PhysicsEngine physicsEngine) { _component = go.GetComponentInChildren(); _player = player; - _simulationSystemGroup = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged(); + _physicsEngine = physicsEngine; } void IApi.OnInit(BallManager ballManager) @@ -92,7 +92,7 @@ private void OnTeleport() private void Eject() { if (_component.EjectDelay > 0) { - _simulationSystemGroup.ScheduleAction((int)math.round(_component.EjectDelay * 1000f), TriggerEjectCoil); + _physicsEngine.ScheduleAction((int)math.round(_component.EjectDelay * 1000f), TriggerEjectCoil); } else { TriggerEjectCoil(); @@ -112,4 +112,3 @@ void IApi.OnDestroy() } } } - diff --git a/package.json b/package.json index d22a023ef..250dbf804 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "unity": "2021.3", "unityRelease": "0f1", "dependencies": { - "com.unity.entities": "1.0.0-pre.15", + "com.unity.entities": "1.0.16", "com.unity.formats.fbx": "4.1.2", "com.unity.inputsystem": "1.3.0", "com.unity.ugui": "1.0.0", From 259acfd06cfbcdbcd5427792058984ea087d5193 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 14 Oct 2023 23:00:54 +0200 Subject: [PATCH 093/159] fix: Don't set active table when hierarchy is disabled. --- .../VisualPinball.Unity.Editor/Common/TableSelectorHook.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TableSelectorHook.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TableSelectorHook.cs index f04d0e46b..f921e7fd9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TableSelectorHook.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Common/TableSelectorHook.cs @@ -50,7 +50,7 @@ private static void SetTableFromSelection() // find parent in hierarchy var selectedTable = Selection.activeGameObject.GetComponentInParent(); - if (selectedTable != null) { + if (selectedTable != null && Selection.activeGameObject.activeInHierarchy) { TableSelector.Instance.SelectedTable = selectedTable; } } @@ -67,7 +67,7 @@ private static TableComponent FindTableInHierarchy() // try root objects first foreach (var go in rootObjects) { var ta = go.GetComponent(); - if (ta != null) { + if (ta != null && ta.isActiveAndEnabled) { return ta; } } From 57e2fec028edf3dce4456b00969d171ca37a7532 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 14 Oct 2023 23:23:49 +0200 Subject: [PATCH 094/159] jobs: Fix physics engine initialization in player. --- .../Game/Engine/DefaultGamelogicEngine.cs | 2 +- .../VisualPinball.Unity/Game/Player.cs | 60 +++++++++++-------- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Engine/DefaultGamelogicEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Engine/DefaultGamelogicEngine.cs index d5c77df18..7f6c21b5b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Engine/DefaultGamelogicEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Engine/DefaultGamelogicEngine.cs @@ -161,7 +161,7 @@ public class DefaultGamelogicEngine : MonoBehaviour, IGamelogicEngine private BallManager _ballManager; private bool _frameSent; private PlayfieldComponent _playfieldComponent; - private const float FlipperLag = 0.5f; + private const float FlipperLag = 0f; private readonly Dictionary _switchTime = new(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index 01b89ea42..c8e96ef55 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -90,6 +90,15 @@ public class Player : MonoBehaviour private PlayfieldComponent _playfieldComponent; private PhysicsEngine _physicsEngine; + private PhysicsEngine PhysicsEngine { + get { + if (_physicsEngine == null) { + _physicsEngine = GetComponent(); + } + return _physicsEngine; + } + } + #region Access internal IApiSwitch Switch(ISwitchDeviceComponent component, string switchItem) => component != null ? _switchPlayer.Switch(component, switchItem) : null; @@ -125,7 +134,6 @@ private void Awake() DebugLogger.ClearLog(); _tableComponent = GetComponent(); _playfieldComponent = GetComponentInChildren(); - _physicsEngine = GetComponent(); var engineComponent = GetComponent(); _apis.Add(TableApi); @@ -139,7 +147,7 @@ private void Awake() _lampPlayer.Awake(this, _tableComponent, GamelogicEngine); _coilPlayer.Awake(this, _tableComponent, GamelogicEngine, _lampPlayer, _wirePlayer); _switchPlayer.Awake(_tableComponent, GamelogicEngine, _inputManager); - _wirePlayer.Awake(_tableComponent, _inputManager, _switchPlayer, this, _physicsEngine); + _wirePlayer.Awake(_tableComponent, _inputManager, _switchPlayer, this, PhysicsEngine); _displayPlayer.Awake(GamelogicEngine); } } @@ -192,22 +200,22 @@ private void OnDestroy() public void RegisterBumper(BumperComponent component) { - Register(new BumperApi(component.gameObject, this, _physicsEngine), component); + Register(new BumperApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterFlipper(FlipperComponent component) { - Register(new FlipperApi(component.gameObject, this, _physicsEngine), component); + Register(new FlipperApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterDropTarget(DropTargetComponent component) { - Register(new DropTargetApi(component.gameObject, this, _physicsEngine), component); + Register(new DropTargetApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterGate(GateComponent component) { - Register(new GateApi(component.gameObject, this, _physicsEngine), component); + Register(new GateApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterGateLifter(GateLifterComponent component) @@ -217,12 +225,12 @@ public void RegisterGateLifter(GateLifterComponent component) public void RegisterHitTarget(HitTargetComponent component) { - Register(new HitTargetApi(component.gameObject, this, _physicsEngine), component); + Register(new HitTargetApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterKicker(KickerComponent component) { - Register(new KickerApi(component.gameObject, this, _physicsEngine), component); + Register(new KickerApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterLamp(LightComponent component) @@ -237,32 +245,32 @@ public void RegisterLampGroup(LightGroupComponent component) public void RegisterStepRotator(StepRotatorMechComponent component) { - Register(new StepRotatorMechApi(component.gameObject, this, _physicsEngine), component); + Register(new StepRotatorMechApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterScoreMotorComponent(ScoreMotorComponent component) { - Register(new ScoreMotorApi(component.gameObject, this, _physicsEngine), component); + Register(new ScoreMotorApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterDropTargetBankComponent(DropTargetBankComponent component) { - Register(new DropTargetBankApi(component.gameObject, this, _physicsEngine), component); + Register(new DropTargetBankApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterCollisionSwitchComponent(CollisionSwitchComponent component) { - Register(new CollisionSwitchApi(component.gameObject, this, _physicsEngine), component); + Register(new CollisionSwitchApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterSlingshotComponent(SlingshotComponent component) { - Register(new SlingshotApi(component.gameObject, this, _physicsEngine), component); + Register(new SlingshotApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterPlunger(PlungerComponent component, InputActionReference actionRef) { - var plungerApi = new PlungerApi(component.gameObject, this, _physicsEngine); + var plungerApi = new PlungerApi(component.gameObject, this, PhysicsEngine); Register(plungerApi, component); if (actionRef != null) { @@ -273,53 +281,53 @@ public void RegisterPlunger(PlungerComponent component, InputActionReference act public void RegisterPlayfield(GameObject go) { - PlayfieldApi = new PlayfieldApi(go, this, _physicsEngine); + PlayfieldApi = new PlayfieldApi(go, this, PhysicsEngine); _colliderGenerators.Add(PlayfieldApi); } public void RegisterPrimitive(PrimitiveComponent component) { - Register(new PrimitiveApi(component.gameObject, this, _physicsEngine), component); + Register(new PrimitiveApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterRamp(RampComponent component) { - Register(new RampApi(component.gameObject, this, _physicsEngine), component); + Register(new RampApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterRubber(RubberComponent component) { - Register(new RubberApi(component.gameObject, this, _physicsEngine), component); + Register(new RubberApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterSpinner(SpinnerComponent component) { - Register(new SpinnerApi(component.gameObject, this, _physicsEngine), component); + Register(new SpinnerApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterSurface(SurfaceComponent component) { - Register(new SurfaceApi(component.gameObject, this, _physicsEngine), component); + Register(new SurfaceApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterTeleporter(TeleporterComponent component) { - Register(new TeleporterApi(component.gameObject, this, _physicsEngine), component); + Register(new TeleporterApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterTrigger(TriggerComponent component) { - Register(new TriggerApi(component.gameObject, this, _physicsEngine), component); + Register(new TriggerApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterTrough(TroughComponent component) { - Register(new TroughApi(component.gameObject, this, _physicsEngine), component); + Register(new TroughApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterMetalWireGuide(MetalWireGuideComponent component) { - Register(new MetalWireGuideApi(component.gameObject, this, _physicsEngine), component); + Register(new MetalWireGuideApi(component.gameObject, this, PhysicsEngine), component); } private void Register(TApi api, MonoBehaviour component) where TApi : IApi @@ -394,8 +402,8 @@ private void RegisterCollider(int itemId, IApiColliderGenerator apiColl) #region Events - public void ScheduleAction(int timeMs, Action action) => _physicsEngine.ScheduleAction(timeMs, action); - public void ScheduleAction(uint timeMs, Action action) => _physicsEngine.ScheduleAction(timeMs, action); + public void ScheduleAction(int timeMs, Action action) => PhysicsEngine.ScheduleAction(timeMs, action); + public void ScheduleAction(uint timeMs, Action action) => PhysicsEngine.ScheduleAction(timeMs, action); public void OnEvent(in EventData eventData) { From 00b044da5ddd93a6180a246dd049481299b8a1f8 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 14 Oct 2023 23:40:58 +0200 Subject: [PATCH 095/159] jobs: Fix plunger --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 1 + .../VPT/Plunger/PlungerApi.cs | 93 ++++++++----------- 2 files changed, 40 insertions(+), 54 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 78dcaf0e2..b1425ca48 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -83,6 +83,7 @@ public void ScheduleAction(uint timeoutMs, Action action) internal ref BallData BallState(int itemId) => ref _ballStates.GetValueByRef(itemId); internal ref FlipperState FlipperState(int itemId) => ref _flipperStates.GetValueByRef(itemId); internal ref KickerState KickerState(int itemId) => ref _kickerStates.GetValueByRef(itemId); + internal ref PlungerState PlungerState(int itemId) => ref _plungerStates.GetValueByRef(itemId); internal void SetBallInsideOf(int ballId, int itemId) => _insideOfs.SetInsideOf(itemId, ballId); internal uint TimeMsec => _physicsEnv[0].TimeMsec; internal void Register(T item) where T : MonoBehaviour diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs index 6dc349244..7ca9c3cd2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerApi.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using System; -using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using UnityEngine.InputSystem; using VisualPinball.Engine.VPT.Plunger; @@ -67,11 +65,9 @@ internal PlungerApi(GameObject go, Player player, PhysicsEngine physicsEngine) : internal void OnAnalogPlunge(InputAction.CallbackContext ctx) { - // fixme job - // var pos = ctx.ReadValue(); // 0 = resting pos, 1 = pulled back - // var movementData = EntityManager.GetComponentData(Entity); - // movementData.AnalogPosition = pos; - // EntityManager.SetComponentData(Entity, movementData); + var pos = ctx.ReadValue(); // 0 = resting pos, 1 = pulled back + ref var plungerState = ref PhysicsEngine.PlungerState(ItemId); + plungerState.Movement.AnalogPosition = pos; } void IApi.OnInit(BallManager ballManager) @@ -89,57 +85,46 @@ void IApi.OnDestroy() public void PullBack() { - // fixme job - // var collComponent = GameObject.GetComponent(); - // if (!collComponent) { - // return; - // } - // var movementData = EntityManager.GetComponentData(Entity); - // var velocityData = EntityManager.GetComponentData(Entity); - // - // if (DoRetract) { - // PlungerCommands.PullBackAndRetract(collComponent.SpeedPull, ref velocityData, ref movementData); - // - // } else { - // PlungerCommands.PullBack(collComponent.SpeedPull, ref velocityData, ref movementData); - // } - // - // EntityManager.SetComponentData(Entity, movementData); - // EntityManager.SetComponentData(Entity, velocityData); + var collComponent = GameObject.GetComponent(); + if (!collComponent) { + return; + } + + ref var plungerState = ref PhysicsEngine.PlungerState(ItemId); + if (DoRetract) { + PlungerCommands.PullBackAndRetract(collComponent.SpeedPull, ref plungerState.Velocity, ref plungerState.Movement); + + } else { + PlungerCommands.PullBack(collComponent.SpeedPull, ref plungerState.Velocity, ref plungerState.Movement); + } } public void Fire() { - // fixme job - // var collComponent = GameObject.GetComponent(); - // if (!collComponent) { - // return; - // } - // var movementData = EntityManager.GetComponentData(Entity); - // var velocityData = EntityManager.GetComponentData(Entity); - // var staticData = EntityManager.GetComponentData(Entity); - // - // // check for an auto plunger - // if (collComponent.IsAutoPlunger) { - // // Auto Plunger - this models a "Launch Ball" button or a - // // ROM-controlled launcher, rather than a player-operated - // // spring plunger. In a physical machine, this would be - // // implemented as a solenoid kicker, so the amount of force - // // is constant (modulo some mechanical randomness). Simulate - // // this by triggering a release from the maximum retracted - // // position. - // PlungerCommands.Fire(1f, ref velocityData, ref movementData, in staticData); - // - // } else { - // // Regular plunger - trigger a release from the current - // // position, using the keyboard firing strength. - // - // var pos = (movementData.Position - staticData.FrameEnd) / (staticData.FrameStart - staticData.FrameEnd); - // PlungerCommands.Fire(pos, ref velocityData, ref movementData, in staticData); - // } - // - // EntityManager.SetComponentData(Entity, movementData); - // EntityManager.SetComponentData(Entity, velocityData); + var collComponent = GameObject.GetComponent(); + if (!collComponent) { + return; + } + ref var plungerState = ref PhysicsEngine.PlungerState(ItemId); + + // check for an auto plunger + if (collComponent.IsAutoPlunger) { + // Auto Plunger - this models a "Launch Ball" button or a + // ROM-controlled launcher, rather than a player-operated + // spring plunger. In a physical machine, this would be + // implemented as a solenoid kicker, so the amount of force + // is constant (modulo some mechanical randomness). Simulate + // this by triggering a release from the maximum retracted + // position. + PlungerCommands.Fire(1f, ref plungerState.Velocity, ref plungerState.Movement, in plungerState.Static); + + } else { + // Regular plunger - trigger a release from the current + // position, using the keyboard firing strength. + + var pos = (plungerState.Movement.Position - plungerState.Static.FrameEnd) / (plungerState.Static.FrameStart - plungerState.Static.FrameEnd); + PlungerCommands.Fire(pos, ref plungerState.Velocity, ref plungerState.Movement, in plungerState.Static); + } } IApiCoil IApiCoilDevice.Coil(string deviceItem) => Coil(deviceItem); From fbf62adbb2d41a7851415c46bde746947dc8182d Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 14 Oct 2023 23:46:55 +0200 Subject: [PATCH 096/159] jobs: Properly destroy balls. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 9 +++++++++ .../VPT/Ball/BallManager.cs | 20 +++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index b1425ca48..3db5a3122 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -113,6 +113,15 @@ internal void Register(T item) where T : MonoBehaviour case TriggerComponent c: _triggerStates[itemId] = c.CreateState(); break; } } + + internal Transform UnregisterBall(int ballId) + { + var transform = _transforms[ballId]; + _transforms.Remove(ballId); + _ballStates.Remove(ballId); + return transform; + } + internal void EnableCollider(int itemId) { if (_disabledCollisionItems.Contains(itemId)) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index c8a176da7..33a25ca15 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -79,21 +79,11 @@ public void CreateBall(IBallCreationPosition ballCreator, float radius, float ma public void DestroyBall(int ballId) { - // fixme job - // var ballGo = _player.Balls[ballEntity]; - // _player.BallDestroyed(ballEntity, ballGo); - // - // // destroy game object - // Object.DestroyImmediate(ballGo); - // _player.Balls.Remove(ballEntity); - // - // // destroy entity - // World.DefaultGameObjectInjectionWorld - // .GetOrCreateSystemManaged() - // .CreateCommandBuffer() - // .DestroyEntity(ballEntity); - // - // NumBalls--; + var ballTransform = _physicsEngine.UnregisterBall(ballId); + _player.BallDestroyed(ballId, ballTransform.gameObject); + + // destroy game object + Object.DestroyImmediate(ballTransform.gameObject); } } } From 0159cfb7ee4d2fcc741622e5e35d6dd2bd25b9b0 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 00:07:57 +0200 Subject: [PATCH 097/159] jobs: Port remaining API code to new physics. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 7 ++++ .../VisualPinball.Unity/Game/Player.cs | 2 +- .../VPT/Bumper/BumperApi.cs | 11 +++--- .../VisualPinball.Unity/VPT/CollidableApi.cs | 11 ------ .../VPT/Flipper/FlipperApi.cs | 6 ++-- .../VisualPinball.Unity/VPT/Gate/GateApi.cs | 12 +++---- .../VPT/Gate/GateLifterApi.cs | 9 ++--- .../VPT/HitTarget/DropTargetApi.cs | 31 ++++++++-------- .../VPT/Mech/RotatorComponent.cs | 35 +++++++++---------- 9 files changed, 56 insertions(+), 68 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 3db5a3122..252a40629 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -81,9 +81,16 @@ public void ScheduleAction(uint timeoutMs, Action action) internal void Schedule(InputAction action) => _inputActions.Enqueue(action); internal ref BallData BallState(int itemId) => ref _ballStates.GetValueByRef(itemId); + internal ref BumperState BumperState(int itemId) => ref _bumperStates.GetValueByRef(itemId); internal ref FlipperState FlipperState(int itemId) => ref _flipperStates.GetValueByRef(itemId); + internal ref GateState GateState(int itemId) => ref _gateStates.GetValueByRef(itemId); + internal ref DropTargetState DropTargetState(int itemId) => ref _dropTargetStates.GetValueByRef(itemId); + internal ref HitTargetState HitTargetState(int itemId) => ref _hitTargetStates.GetValueByRef(itemId); internal ref KickerState KickerState(int itemId) => ref _kickerStates.GetValueByRef(itemId); internal ref PlungerState PlungerState(int itemId) => ref _plungerStates.GetValueByRef(itemId); + internal ref SpinnerState SpinnerState(int itemId) => ref _spinnerStates.GetValueByRef(itemId); + internal ref SurfaceState SurfaceState(int itemId) => ref _surfaceStates.GetValueByRef(itemId); + internal ref TriggerState TriggerState(int itemId) => ref _triggerStates.GetValueByRef(itemId); internal void SetBallInsideOf(int ballId, int itemId) => _insideOfs.SetInsideOf(itemId, ballId); internal uint TimeMsec => _physicsEnv[0].TimeMsec; internal void Register(T item) where T : MonoBehaviour diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index c8e96ef55..d5f59cd8e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -220,7 +220,7 @@ public void RegisterGate(GateComponent component) public void RegisterGateLifter(GateLifterComponent component) { - Register(new GateLifterApi(component.gameObject, this), component); + Register(new GateLifterApi(component.gameObject, this, PhysicsEngine), component); } public void RegisterHitTarget(HitTargetComponent component) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs index 6eed53ebc..1a3dc9149 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs @@ -56,12 +56,11 @@ public BumperApi(GameObject go, Player player, PhysicsEngine physicsEngine) : ba void IApiSwitch.RemoveWireDest(string destId) => RemoveWireDest(destId); void IApiCoil.OnCoil(bool enabled) { - // fixme job - // if (enabled) { - // var ringAnimation = EntityManager.GetComponentData(Entity); - // ringAnimation.IsHit = true; - // EntityManager.SetComponentData(Entity, ringAnimation); - // } + if (!enabled) { + return; + } + ref var bumperState = ref PhysicsEngine.BumperState(ItemId); + bumperState.RingAnimation.IsHit = true; } void IApiWireDest.OnChange(bool enabled) => (this as IApiCoil).OnCoil(enabled); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs index 9b572111a..cbeb1c7a2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs @@ -25,17 +25,6 @@ public abstract class CollidableApi : I where TCollidableComponent : ColliderComponent where TData : ItemData { - public bool IsCollidable - { - get => true; // fixme job _simulateCycleSystemGroup != null && _simulateCycleSystemGroup.ItemsColliding[Entity]; - set { - // fixme job - // if (_simulateCycleSystemGroup != null) { - // _simulateCycleSystemGroup.ItemsColliding[Entity] = value; - // } - } - } - protected readonly int ItemId; protected readonly TCollidableComponent ColliderComponent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs index f972d83cd..72aa99a30 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs @@ -117,10 +117,8 @@ public void RotateToStart() internal float StartAngle { set { - // fixme job - // var staticData = EntityManager.GetComponentData(Entity); - // staticData.AngleStart = value; - // EntityManager.SetComponentData(Entity, staticData); + ref var flipperState = ref PhysicsEngine.FlipperState(ItemId); + flipperState.Static.AngleStart = value; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs index 575e3cdea..f1053382d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs @@ -16,6 +16,8 @@ using System; using System.Collections.Generic; +using Unity.Entities; +using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.VPT.Gate; @@ -78,12 +80,10 @@ public GateApi(GameObject go, Player player, PhysicsEngine physicsEngine) : base public void Lift(float speed, float angleDeg) { - // fixme job - // var data = EntityManager.GetComponentData(Entity); - // data.IsLifting = true; - // data.LiftSpeed = speed; - // data.LiftAngle = math.radians(angleDeg); - // EntityManager.SetComponentData(Entity, data); + ref var gateState = ref PhysicsEngine.GateState(ItemId); + gateState.Movement.IsLifting = true; + gateState.Movement.LiftSpeed = speed; + gateState.Movement.LiftAngle = math.radians(angleDeg); } #region Wiring diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateLifterApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateLifterApi.cs index eaf5fbd6f..3a25993eb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateLifterApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateLifterApi.cs @@ -28,6 +28,7 @@ public class GateLifterApi : IApi, IApiCoilDevice, IApiWireDeviceDest public event EventHandler Init; private readonly Player _player; + private readonly PhysicsEngine _physicsEngine; private readonly GateComponent _gateComponent; private readonly GateLifterComponent _gateLifterComponent; private readonly GateColliderComponent _gateColliderComponent; @@ -35,12 +36,13 @@ public class GateLifterApi : IApi, IApiCoilDevice, IApiWireDeviceDest private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); private GateApi _gateApi; - internal GateLifterApi(GameObject go, Player player) + internal GateLifterApi(GameObject go, Player player, PhysicsEngine physicsEngine) { _gateComponent = go.GetComponent(); _gateColliderComponent = go.GetComponent(); _gateLifterComponent = go.GetComponent(); _player = player; + _physicsEngine = physicsEngine; } void IApi.OnInit(BallManager ballManager) @@ -72,8 +74,7 @@ private void OnLifterCoilEnabled() Logger.Warn("Lifter coil enabled, but gate collider not found."); return; } - - _gateApi.IsCollidable = false; + _physicsEngine.DisableCollider(((ICollidableComponent)_gateColliderComponent).ItemId); _gateApi.Lift(_gateLifterComponent.AnimationSpeed, _gateLifterComponent.LiftedAngleDeg); } @@ -84,7 +85,7 @@ private void OnLifterCoilDisabled() return; } - _gateApi.IsCollidable = true; + _physicsEngine.EnableCollider(((ICollidableComponent)_gateColliderComponent).ItemId); _gateApi.Lift(_gateLifterComponent.AnimationSpeed, 0f); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs index 5c7e661bb..66bc87543 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetApi.cs @@ -50,7 +50,7 @@ public class DropTargetApi : CollidableApiThrown if target is not a drop target (but a hit target, which can't be dropped) public bool IsDropped { - get => false; // fixme job EntityManager.GetComponentData(Entity).IsDropped; + get => PhysicsEngine.DropTargetState(ItemId).Animation.IsDropped; set => SetIsDropped(value); } @@ -71,22 +71,19 @@ public void OnDropStatusChanged(bool isDropped, int ballId) /// private void SetIsDropped(bool isDropped) { - // fixme job - // var data = EntityManager.GetComponentData(Entity); - // if (data.IsDropped != isDropped) { - // data.MoveAnimation = true; - // if (isDropped) { - // data.MoveDown = true; - // } - // else { - // data.MoveDown = false; - // data.TimeStamp = World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged().TimeMsec; - // } - // } else { - // data.IsDropped = isDropped; - // } - // - // EntityManager.SetComponentData(Entity, data); + ref var state = ref PhysicsEngine.DropTargetState(ItemId); + if (state.Animation.IsDropped != isDropped) { + state.Animation.MoveAnimation = true; + if (isDropped) { + state.Animation.MoveDown = true; + } + else { + state.Animation.MoveDown = false; + state.Animation.TimeStamp = PhysicsEngine.TimeMsec; + } + } else { + state.Animation.IsDropped = isDropped; + } } #region Wiring diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs index 19c1cff90..5c64ebed6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs @@ -56,7 +56,7 @@ public IRotatableComponent[] RotateWith { private Player _player; private KickerApi[] _kickers; - private (KickerApi kicker, float distance, float angle, int ballId)[] _ballEntities; + private (KickerApi kicker, float distance, float angle, int ballId)[] _balls; private Dictionary _rotatingObjectDistances = new(); private static EntityManager EntityManager => World.DefaultGameObjectInjectionWorld.EntityManager; @@ -85,7 +85,7 @@ private void Start() public void StartRotating() { var pos = Target.RotatedPosition; - _ballEntities = _kickers.Where(k => k.HasBall()).Select(k => ( + _balls = _kickers.Where(k => k.HasBall()).Select(k => ( k, math.distance(pos, k.Position.xy), math.sign(pos.x - k.Position.x) * Vector2.Angle(k.Position.xy - pos, new float2(0f, -1f)), @@ -109,23 +109,20 @@ public void UpdateRotation(float angleDeg) ); } - // fixme job - // // rotate ball(s) in kicker(s) - // foreach (var (kicker, distance, angle, ballEntity) in _ballEntities) { - // if (!kicker.HasBall()) { - // return; - // } - // var ballData = EntityManager.GetComponentData(ballEntity); - // ballData.Position = new float3( - // pos.x -distance * math.sin(math.radians(angleDeg + angle)), - // pos.y -distance * math.cos(math.radians(angleDeg + angle)), - // ballData.Position.z - // ); - // ballData.Velocity = float3.zero; - // ballData.AngularMomentum = float3.zero; - // - // EntityManager.SetComponentData(ballEntity, ballData); - // } + // rotate ball(s) in kicker(s) + foreach (var (kicker, distance, angle, ballId) in _balls) { + if (!kicker.HasBall()) { + return; + } + ref var ballData = ref GetComponentInParent().BallState(ballId); + ballData.Position = new float3( + pos.x -distance * math.sin(math.radians(angleDeg + angle)), + pos.y -distance * math.cos(math.radians(angleDeg + angle)), + ballData.Position.z + ); + ballData.Velocity = float3.zero; + ballData.AngularMomentum = float3.zero; + } } #endregion From aa4817527366b27464f9089b397ad8b59a9e34b0 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 01:36:08 +0200 Subject: [PATCH 098/159] jobs: Add dynamic broad phase to physics cycle. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 32 +++++++----- .../Game/PhysicsDynamicBroadPhase.cs | 50 +++++++++++++++++++ .../Game/PhysicsDynamicBroadPhase.cs.meta | 3 ++ .../VisualPinball.Unity/Game/PhysicsEngine.cs | 5 ++ .../Game/PhysicsStaticBroadPhase.cs | 4 +- .../Game/PhysicsStaticNarrowPhase.cs | 17 ++++--- .../Game/PhysicsUpdateJob.cs | 6 ++- .../Physics/Collision/Aabb.cs | 5 ++ .../VisualPinball.Unity/VPT/Ball/BallData.cs | 1 + .../VPT/Playfield/PlayfieldComponent.cs | 2 + 10 files changed, 101 insertions(+), 24 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index f8f35fda1..2eb8845c4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . using System; +using NativeTrees; using Unity.Collections; using Unity.Profiling; using VisualPinball.Engine.Common; @@ -27,37 +28,38 @@ public struct PhysicsCycle : IDisposable { private NativeList _contacts; - [NativeDisableParallelForRestriction] - private NativeList _overlappingColliders; - private static readonly ProfilerMarker PerfMarker = new("PhysicsCycle"); private static readonly ProfilerMarker PerfMarkerBroadPhase = new("BroadPhase"); private static readonly ProfilerMarker PerfMarkerNarrowPhase = new("NarrowPhase"); private static readonly ProfilerMarker PerfMarkerDisplacement = new("Displacement"); private static readonly ProfilerMarker PerfMarkerCollision = new("Collision"); private static readonly ProfilerMarker PerfMarkerContacts = new("Contacts"); + private static readonly ProfilerMarker PerfMarkerBallOctree = new("CreateBallOctree"); + private static readonly ProfilerMarker PerfMarkerDynamicBroadPhase = new("DynamicBroadPhase"); + private static readonly ProfilerMarker PerfMarkerDynamicNarrowPhase = new("DynamicNarrowPhase"); public PhysicsCycle(Allocator a) { _contacts = new NativeList(a); - _overlappingColliders = new NativeList(a); } - internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) + internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref NativeParallelHashSet overlappingColliders, float dTime, uint timeMs) { PerfMarker.Begin(); var staticCounts = PhysicsConstants.StaticCnts; - + while (dTime > 0) { - + var hitTime = dTime; // begin time search from now ... until delta ends - + // todo apply flipper time - + // clear contacts _contacts.Clear(); - // todo dynamic broad phase + PerfMarkerBallOctree.Begin(); + var ballOctree = PhysicsDynamicBroadPhase.CreateOctree(ref state.Balls, in playfieldBounds); + PerfMarkerBallOctree.End(); using (var enumerator = state.Balls.GetEnumerator()) { while (enumerator.MoveNext()) { @@ -67,14 +69,19 @@ internal void Simulate(ref PhysicsState state, float dTime, uint timeMs) continue; } + // dynamic broad phase + PerfMarkerDynamicBroadPhase.Begin(); + PhysicsDynamicBroadPhase.FindOverlaps(in ballOctree, in ball, ref overlappingColliders, ref state.Balls); + PerfMarkerDynamicBroadPhase.End(); + // static broad phase PerfMarkerBroadPhase.Begin(); - PhysicsStaticBroadPhase.FindOverlaps(in state.Octree, in ball, ref _overlappingColliders); + PhysicsStaticBroadPhase.FindOverlaps(in state.Octree, in ball, ref overlappingColliders); PerfMarkerBroadPhase.End(); // static narrow phase PerfMarkerNarrowPhase.Begin(); - PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, in _overlappingColliders, ref _contacts, ref state); + PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, ref overlappingColliders, ref _contacts, ref state); PerfMarkerNarrowPhase.End(); // todo dynamic narrow phase @@ -185,7 +192,6 @@ private static void ApplyStaticTime(ref float hitTime, ref float staticCounts, i public void Dispose() { _contacts.Dispose(); - _overlappingColliders.Dispose(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs new file mode 100644 index 000000000..eb41a1366 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs @@ -0,0 +1,50 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using NativeTrees; +using Unity.Collections; +using VisualPinball.Unity.Collections; + +namespace VisualPinball.Unity +{ + public static class PhysicsDynamicBroadPhase + { + internal static NativeOctree CreateOctree(ref NativeParallelHashMap balls, in AABB playfieldBounds) + { + var octree = new NativeOctree(playfieldBounds, 16, 10, Allocator.TempJob); + using var enumerator = balls.GetEnumerator(); + while (enumerator.MoveNext()) { + ref var ball = ref enumerator.Current.Value; + octree.Insert(ball.Id, ball.Aabb); + } + return octree; + } + + internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeParallelHashSet overlappingBalls, ref NativeParallelHashMap balls) + { + overlappingBalls.Clear(); + octree.RangeAABBUnique(ball.Aabb, overlappingBalls); + using var ob = overlappingBalls.ToNativeArray(Allocator.Temp); + for (var i = 0; i < ob.Length; i ++) { + var overlappingBallId = ob[i]; + ref var overlappingBall = ref balls.GetValueByRef(overlappingBallId); + if (overlappingBallId == ball.Id || overlappingBall.IsFrozen) { + overlappingBalls.Remove(overlappingBallId); + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs.meta new file mode 100644 index 000000000..fe393901e --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 39f41526d2d74c068970e5b36dbfaca8 +timeCreated: 1697322346 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 252a40629..5a1bfe5c8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -24,6 +24,7 @@ using UnityEngine; using VisualPinball.Unity.Collections; using VisualPinballUnity; +using AABB = NativeTrees.AABB; using Debug = UnityEngine.Debug; namespace VisualPinball.Unity @@ -32,6 +33,7 @@ public class PhysicsEngine : MonoBehaviour { #region States + [NonSerialized] private AABB _playfieldBounds; [NonSerialized] private InsideOfs _insideOfs; [NonSerialized] private NativeOctree _octree; [NonSerialized] private BlobAssetReference _colliders; @@ -173,6 +175,7 @@ private void Start() // create octree var elapsedMs = sw.Elapsed.TotalMilliseconds; var playfieldBounds = GetComponentInChildren().Bounds; + _playfieldBounds = GetComponentInChildren().Bounds; _octree = new NativeOctree(playfieldBounds, 1024, 10, Allocator.Persistent); sw.Restart(); @@ -215,6 +218,8 @@ private void Update() SurfaceStates = _surfaceStates, TriggerStates = _triggerStates, DisabledCollisionItems = _disabledCollisionItems, + PlayfieldBounds = _playfieldBounds, + OverlappingColliders = new NativeParallelHashSet(0, Allocator.TempJob) }; var env = _physicsEnv[0]; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs index ba744f572..f93b2dea8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs @@ -21,10 +21,10 @@ namespace VisualPinball.Unity { public static class PhysicsStaticBroadPhase { - internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeList overlappingColliders) + internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeParallelHashSet overlappingColliders) { overlappingColliders.Clear(); - octree.RangeAABB(ball.Aabb, overlappingColliders); + octree.RangeAABBUnique(ball.Aabb, overlappingColliders); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index 76216d31c..58e11bbfe 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -25,7 +25,7 @@ public static class PhysicsStaticNarrowPhase internal static void FindNextCollision( float hitTime, ref BallData ball, - in NativeList overlappingColliders, + ref NativeParallelHashSet overlappingColliders, ref NativeList contacts, ref PhysicsState state ) @@ -33,13 +33,16 @@ ref PhysicsState state // init contacts and event ball.CollisionEvent.ClearCollider(hitTime); // search upto current hit time - for (var i = 0; i < overlappingColliders.Length; i++) { - if (!state.IsColliderActive(overlappingColliders[i])) { - continue; + using (var enumerator = overlappingColliders.GetEnumerator()) { + while (enumerator.MoveNext()) { + var overlappingColliderId = enumerator.Current; + if (!state.IsColliderActive(overlappingColliderId)) { + continue; + } + var newCollEvent = new CollisionEventData(); + var newTime = state.HitTest(overlappingColliderId, ref ball, ref newCollEvent, ref contacts, ref state); + SaveCollisions(ref ball, ref newCollEvent, ref contacts, overlappingColliderId, newTime); } - var newCollEvent = new CollisionEventData(); - var newTime = state.HitTest(overlappingColliders[i], ref ball, ref newCollEvent, ref contacts, ref state); - SaveCollisions(ref ball, ref newCollEvent, ref contacts, overlappingColliders[i], newTime); } // no negative time allowed diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs index d160e2b81..7d1093987 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs @@ -31,11 +31,14 @@ internal struct PhysicsUpdateJob : IJob public float DeltaTimeMs; + [NativeDisableParallelForRestriction] + public NativeParallelHashSet OverlappingColliders; public NativeArray PhysicsEnv; public NativeOctree Octree; public BlobAssetReference Colliders; public InsideOfs InsideOfs; public NativeQueue.ParallelWriter Events; + public AABB PlayfieldBounds; public NativeParallelHashMap Balls; public NativeParallelHashMap BumperStates; @@ -50,7 +53,6 @@ internal struct PhysicsUpdateJob : IJob public NativeParallelHashMap TriggerStates; public NativeParallelHashSet DisabledCollisionItems; - public void Execute() { var env = PhysicsEnv[0]; @@ -105,7 +107,7 @@ public void Execute() #endregion // primary physics loop - cycle.Simulate(ref state, physicsDiffTime, timeMsec); + cycle.Simulate(ref state, in PlayfieldBounds, ref OverlappingColliders, physicsDiffTime, timeMsec); // ball trail, keep old pos of balls using (var enumerator = state.Balls.GetEnumerator()) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs index 3ff639436..4f284b30e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs @@ -102,6 +102,11 @@ public static implicit operator NativeTrees.AABB(Aabb aabb) return new NativeTrees.AABB(aabb.Min, aabb.Max); } + public static implicit operator NativeTrees.AABB2D(Aabb aabb) + { + return new NativeTrees.AABB2D(new float2(aabb.Min.x, aabb.Min.y), new float2(aabb.Min.x, aabb.Max.y)); + } + public override string ToString() { return $"Aabb {Left} → {Right} | {Top} ↘ {Bottom} | {ZLow} ↑ {ZHigh}"; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs index f40012ef6..56843bf7f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using NativeTrees; using Unity.Entities; using Unity.Mathematics; using VisualPinballUnity; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs index cde449e1c..b727e9612 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using NativeTrees; using Unity.Entities; using Unity.Mathematics; using UnityEngine; @@ -93,6 +94,7 @@ public class PlayfieldComponent : MainRenderableComponent public Rect3D BoundingBox => new Rect3D(Left, Right, Top, Bottom, TableHeight, GlassHeight); public Aabb Bounds => new Aabb(Left, Right, Top, Bottom, TableHeight, GlassHeight); + public AABB2D Bounds2D => new AABB2D(new float2(Left, Top), new float2(Right, Bottom)); public float3 Gravity { get { From 24add161c23b87b1d9d39f8d33a5cc0e7117d756 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 12:40:16 +0200 Subject: [PATCH 099/159] jobs: Add dynamic narrow phase to physics cycle. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 15 +++-- .../Game/PhysicsDynamicNarrowPhase.cs | 56 +++++++++++++++++++ .../Game/PhysicsDynamicNarrowPhase.cs.meta | 3 + 3 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 2eb8845c4..e15385fbc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -69,11 +69,6 @@ internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref Nati continue; } - // dynamic broad phase - PerfMarkerDynamicBroadPhase.Begin(); - PhysicsDynamicBroadPhase.FindOverlaps(in ballOctree, in ball, ref overlappingColliders, ref state.Balls); - PerfMarkerDynamicBroadPhase.End(); - // static broad phase PerfMarkerBroadPhase.Begin(); PhysicsStaticBroadPhase.FindOverlaps(in state.Octree, in ball, ref overlappingColliders); @@ -84,7 +79,15 @@ internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref Nati PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, ref overlappingColliders, ref _contacts, ref state); PerfMarkerNarrowPhase.End(); - // todo dynamic narrow phase + // dynamic broad phase + PerfMarkerDynamicBroadPhase.Begin(); + PhysicsDynamicBroadPhase.FindOverlaps(in ballOctree, in ball, ref overlappingColliders, ref state.Balls); + PerfMarkerDynamicBroadPhase.End(); + + // dynamic narrow phase + PerfMarkerDynamicNarrowPhase.Begin(); + PhysicsDynamicNarrowPhase.FindNextCollision(ref ball, ref overlappingColliders, ref _contacts, ref state); + PerfMarkerDynamicNarrowPhase.End(); // apply static time ApplyStaticTime(ref hitTime, ref staticCounts, in ball); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs new file mode 100644 index 000000000..8e8509eb2 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs @@ -0,0 +1,56 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Collections; +using VisualPinball.Unity.Collections; + +namespace VisualPinball.Unity +{ + internal static class PhysicsDynamicNarrowPhase + { + + internal static void FindNextCollision(ref BallData ball, ref NativeParallelHashSet collidingBalls, + ref NativeList contacts, ref PhysicsState state) + { + // don't play with frozen balls + if (ball.IsFrozen) { + return; + } + + ref var collEvent = ref ball.CollisionEvent; + using var enumerator = collidingBalls.GetEnumerator(); + while (enumerator.MoveNext()) { + var collidingBallId = enumerator.Current; + ref var collBall = ref state.Balls.GetValueByRef(collidingBallId); + + var newCollEvent = new CollisionEventData(); + var newTime = BallCollider.HitTest(ref newCollEvent, ref ball, in collBall, collEvent.HitTime); + var validHit = newTime >= 0 && !Math.Sign(newTime) && newTime <= collEvent.HitTime; + + if (newCollEvent.IsContact || validHit) { + newCollEvent.SetCollider(collidingBallId, ball.Id); + newCollEvent.HitTime = newTime; + if (newCollEvent.IsContact) { + contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); + + } else { // if (validhit) + collEvent = newCollEvent; + } + } + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs.meta new file mode 100644 index 000000000..cc0db2515 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f8ac8708494e49e28d99ed310112d4c9 +timeCreated: 1697365085 \ No newline at end of file From fae001d070d444583d9ff476dceeee06c74314b9 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 13:40:54 +0200 Subject: [PATCH 100/159] jobs: Add dynamic ball-to-ball collision to physics cycle. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 33 +++--------- .../Game/PhysicsDynamicBroadPhase.cs | 8 +++ .../Game/PhysicsDynamicCollision.cs | 54 +++++++++++++++++++ .../Game/PhysicsDynamicCollision.cs.meta | 3 ++ .../Game/PhysicsDynamicNarrowPhase.cs | 6 ++- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 3 +- .../VisualPinball.Unity/Game/PhysicsState.cs | 4 +- .../Game/PhysicsStaticBroadPhase.cs | 5 ++ .../Game/PhysicsStaticCollision.cs | 20 +++---- .../Game/PhysicsStaticNarrowPhase.cs | 8 ++- .../Game/PhysicsUpdateJob.cs | 12 ++--- .../Physics/Collision/CollisionEventData.cs | 7 ++- .../VPT/HitTarget/DropTargetAnimation.cs | 8 +-- 13 files changed, 118 insertions(+), 53 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index e15385fbc..a14614448 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -29,21 +29,16 @@ public struct PhysicsCycle : IDisposable private NativeList _contacts; private static readonly ProfilerMarker PerfMarker = new("PhysicsCycle"); - private static readonly ProfilerMarker PerfMarkerBroadPhase = new("BroadPhase"); - private static readonly ProfilerMarker PerfMarkerNarrowPhase = new("NarrowPhase"); private static readonly ProfilerMarker PerfMarkerDisplacement = new("Displacement"); private static readonly ProfilerMarker PerfMarkerCollision = new("Collision"); private static readonly ProfilerMarker PerfMarkerContacts = new("Contacts"); - private static readonly ProfilerMarker PerfMarkerBallOctree = new("CreateBallOctree"); - private static readonly ProfilerMarker PerfMarkerDynamicBroadPhase = new("DynamicBroadPhase"); - private static readonly ProfilerMarker PerfMarkerDynamicNarrowPhase = new("DynamicNarrowPhase"); public PhysicsCycle(Allocator a) { _contacts = new NativeList(a); } - internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref NativeParallelHashSet overlappingColliders, float dTime, uint timeMs) + internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref NativeParallelHashSet overlappingColliders, float dTime) { PerfMarker.Begin(); var staticCounts = PhysicsConstants.StaticCnts; @@ -57,9 +52,8 @@ internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref Nati // clear contacts _contacts.Clear(); - PerfMarkerBallOctree.Begin(); + // create octree of ball-to-ball collision var ballOctree = PhysicsDynamicBroadPhase.CreateOctree(ref state.Balls, in playfieldBounds); - PerfMarkerBallOctree.End(); using (var enumerator = state.Balls.GetEnumerator()) { while (enumerator.MoveNext()) { @@ -69,25 +63,11 @@ internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref Nati continue; } - // static broad phase - PerfMarkerBroadPhase.Begin(); + // hit testing PhysicsStaticBroadPhase.FindOverlaps(in state.Octree, in ball, ref overlappingColliders); - PerfMarkerBroadPhase.End(); - - // static narrow phase - PerfMarkerNarrowPhase.Begin(); PhysicsStaticNarrowPhase.FindNextCollision(hitTime, ref ball, ref overlappingColliders, ref _contacts, ref state); - PerfMarkerNarrowPhase.End(); - - // dynamic broad phase - PerfMarkerDynamicBroadPhase.Begin(); PhysicsDynamicBroadPhase.FindOverlaps(in ballOctree, in ball, ref overlappingColliders, ref state.Balls); - PerfMarkerDynamicBroadPhase.End(); - - // dynamic narrow phase - PerfMarkerDynamicNarrowPhase.Begin(); PhysicsDynamicNarrowPhase.FindNextCollision(ref ball, ref overlappingColliders, ref _contacts, ref state); - PerfMarkerDynamicNarrowPhase.End(); // apply static time ApplyStaticTime(ref hitTime, ref staticCounts, in ball); @@ -145,10 +125,11 @@ internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref Nati while (enumerator.MoveNext()) { ref var ball = ref enumerator.Current.Value; - // todo dynamic collision + // dynamic collision + PhysicsDynamicCollision.Collide(hitTime, ref ball, ref state); // static collision - PhysicsStaticCollision.Collide(hitTime, ref ball, timeMs, ref state); + PhysicsStaticCollision.Collide(hitTime, ref ball, ref state); } } PerfMarkerCollision.End(); @@ -173,6 +154,8 @@ internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref Nati } dTime -= hitTime; + + state.SwapBallCollisionHandling = !state.SwapBallCollisionHandling; } PerfMarker.End(); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs index eb41a1366..053f9a0b1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs @@ -16,25 +16,32 @@ using NativeTrees; using Unity.Collections; +using Unity.Profiling; using VisualPinball.Unity.Collections; namespace VisualPinball.Unity { public static class PhysicsDynamicBroadPhase { + private static readonly ProfilerMarker PerfMarkerBallOctree = new("CreateBallOctree"); + private static readonly ProfilerMarker PerfMarkerDynamicBroadPhase = new("DynamicBroadPhase"); + internal static NativeOctree CreateOctree(ref NativeParallelHashMap balls, in AABB playfieldBounds) { + PerfMarkerBallOctree.Begin(); var octree = new NativeOctree(playfieldBounds, 16, 10, Allocator.TempJob); using var enumerator = balls.GetEnumerator(); while (enumerator.MoveNext()) { ref var ball = ref enumerator.Current.Value; octree.Insert(ball.Id, ball.Aabb); } + PerfMarkerBallOctree.End(); return octree; } internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeParallelHashSet overlappingBalls, ref NativeParallelHashMap balls) { + PerfMarkerDynamicBroadPhase.Begin(); overlappingBalls.Clear(); octree.RangeAABBUnique(ball.Aabb, overlappingBalls); using var ob = overlappingBalls.ToNativeArray(Allocator.Temp); @@ -45,6 +52,7 @@ internal static void FindOverlaps(in NativeOctree octree, in BallData ball, overlappingBalls.Remove(overlappingBallId); } } + PerfMarkerDynamicBroadPhase.End(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs new file mode 100644 index 000000000..5c872c88e --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs @@ -0,0 +1,54 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Unity.Profiling; +using VisualPinball.Unity.Collections; + +namespace VisualPinball.Unity +{ + internal static class PhysicsDynamicCollision + { + private static readonly ProfilerMarker PerfMarker = new("DynamicCollision"); + + internal static void Collide(float hitTime, ref BallData ball, ref PhysicsState state) + { + // pick "other" ball + ref var collEvent = ref ball.CollisionEvent; + ref var otherId = ref collEvent.BallId; + + // find balls with hit objects and minimum time + if (otherId != 0 && collEvent.HitTime <= hitTime) { + + PerfMarker.Begin(); + + ref var otherBall = ref state.Balls.GetValueByRef(otherId); + ref var otherCollEvent = ref otherBall.CollisionEvent; + + // now collision, contact and script reactions on active ball (object)+++++++++ + + //this.activeBall = ball; // For script that wants the ball doing the collision + + BallCollider.Collide(ref otherBall, ref ball, in otherCollEvent, in collEvent, + state.SwapBallCollisionHandling); + + // remove trial hit object pointer + collEvent.ClearCollider(); + + PerfMarker.End(); + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs.meta new file mode 100644 index 000000000..2f3439dde --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a8a75d40ec354691b6de0c39c1950933 +timeCreated: 1697366994 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs index 8e8509eb2..46d5adc42 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs @@ -15,12 +15,14 @@ // along with this program. If not, see . using Unity.Collections; +using Unity.Profiling; using VisualPinball.Unity.Collections; namespace VisualPinball.Unity { internal static class PhysicsDynamicNarrowPhase { + private static readonly ProfilerMarker PerfMarkerDynamicNarrowPhase = new("DynamicNarrowPhase"); internal static void FindNextCollision(ref BallData ball, ref NativeParallelHashSet collidingBalls, ref NativeList contacts, ref PhysicsState state) @@ -29,6 +31,7 @@ internal static void FindNextCollision(ref BallData ball, ref NativeParallelHash if (ball.IsFrozen) { return; } + PerfMarkerDynamicNarrowPhase.Begin(); ref var collEvent = ref ball.CollisionEvent; using var enumerator = collidingBalls.GetEnumerator(); @@ -41,7 +44,7 @@ internal static void FindNextCollision(ref BallData ball, ref NativeParallelHash var validHit = newTime >= 0 && !Math.Sign(newTime) && newTime <= collEvent.HitTime; if (newCollEvent.IsContact || validHit) { - newCollEvent.SetCollider(collidingBallId, ball.Id); + newCollEvent.SetBallItem(collidingBallId); newCollEvent.HitTime = newTime; if (newCollEvent.IsContact) { contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); @@ -51,6 +54,7 @@ internal static void FindNextCollision(ref BallData ball, ref NativeParallelHash } } } + PerfMarkerDynamicNarrowPhase.End(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 5a1bfe5c8..928e191ee 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -52,6 +52,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeParallelHashMap _surfaceStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _triggerStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashSet _disabledCollisionItems = new(0, Allocator.Persistent); + [NonSerialized] private bool _swapBallCollisionHandling; #endregion @@ -226,7 +227,7 @@ private void Update() var state = new PhysicsState(ref env, ref _octree, ref _colliders, ref events, ref _insideOfs, ref _ballStates, ref _bumperStates, ref _dropTargetStates, ref _flipperStates, ref _gateStates, ref _hitTargetStates, ref _kickerStates, ref _plungerStates, ref _spinnerStates, - ref _surfaceStates, ref _triggerStates, ref _disabledCollisionItems); + ref _surfaceStates, ref _triggerStates, ref _disabledCollisionItems, ref _swapBallCollisionHandling); // process input while (_inputActions.Count > 0) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 21e574f05..d71c06fd1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -41,6 +41,7 @@ internal struct PhysicsState internal NativeParallelHashMap SurfaceStates; internal NativeParallelHashMap TriggerStates; internal NativeParallelHashSet DisabledCollisionItems; + internal bool SwapBallCollisionHandling; public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAssetReference colliders, ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeParallelHashMap balls, @@ -49,7 +50,7 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs ref NativeParallelHashMap hitTargetStates, ref NativeParallelHashMap kickerStates, ref NativeParallelHashMap plungerStates, ref NativeParallelHashMap spinnerStates, ref NativeParallelHashMap surfaceStates, ref NativeParallelHashMap triggerStates, - ref NativeParallelHashSet disabledCollisionItems) + ref NativeParallelHashSet disabledCollisionItems, ref bool swapBallCollisionHandling) { Env = env; Octree = octree; @@ -68,6 +69,7 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs SurfaceStates = surfaceStates; TriggerStates = triggerStates; DisabledCollisionItems = disabledCollisionItems; + SwapBallCollisionHandling = swapBallCollisionHandling; } internal Collider GetCollider(int colliderId) => Colliders.Value.Colliders[colliderId].Value; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs index f93b2dea8..57a8079ac 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs @@ -16,15 +16,20 @@ using NativeTrees; using Unity.Collections; +using Unity.Profiling; namespace VisualPinball.Unity { public static class PhysicsStaticBroadPhase { + private static readonly ProfilerMarker PerfMarkerBroadPhase = new("BroadPhase"); + internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeParallelHashSet overlappingColliders) { + PerfMarkerBroadPhase.Begin(); overlappingColliders.Clear(); octree.RangeAABBUnique(ball.Aabb, overlappingColliders); + PerfMarkerBroadPhase.End(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index c83d2ad11..042ab6af3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity { internal static class PhysicsStaticCollision { - internal static void Collide(float hitTime, ref BallData ball, uint timeMs, ref PhysicsState state) + internal static void Collide(float hitTime, ref BallData ball, ref PhysicsState state) { // find balls with hit objects and minimum time @@ -31,17 +31,17 @@ internal static void Collide(float hitTime, ref BallData ball, uint timeMs, ref return; } - Collide(ref ball, timeMs, ref state); + Collide(ref ball, ref state); // remove trial hit object pointer ball.CollisionEvent.ClearCollider(); } - private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState state) + private static void Collide(ref BallData ball, ref PhysicsState state) { var colliderId = ball.CollisionEvent.ColliderId; var collider = state.GetCollider(colliderId); - if (CollidesWithItem(ref collider, ref ball, ref state, timeMs)) { + if (CollidesWithItem(ref collider, ref ball, ref state)) { return; } @@ -88,7 +88,7 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta ref var flipperCollider = ref state.Colliders.GetFlipperCollider(colliderId); flipperCollider.Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, ref state.EventQueue, in ball.Id, in flipperState.Tricks, in flipperState.Static, - in flipperState.Velocity, in flipperState.Hit, timeMs + in flipperState.Velocity, in flipperState.Hit, state.Env.TimeMsec ); break; @@ -117,7 +117,7 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta case ColliderType.TriggerCircle: case ColliderType.TriggerLine: - TriggerCollide(ref ball, ref state, in collider, timeMs); + TriggerCollide(ref ball, ref state, in collider); break; case ColliderType.KickerCircle: @@ -128,7 +128,7 @@ private static void Collide(ref BallData ball, uint timeMs, ref PhysicsState sta } } - private static bool CollidesWithItem(ref Collider collider, ref BallData ball, ref PhysicsState state, uint timeMs) + private static bool CollidesWithItem(ref Collider collider, ref BallData ball, ref PhysicsState state) { // hit target var colliderId = ball.CollisionEvent.ColliderId; @@ -152,14 +152,14 @@ private static bool CollidesWithItem(ref Collider collider, ref BallData ball, r // trigger } else if (collider.Header.ItemType == ItemType.Trigger) { - TriggerCollide(ref ball, ref state, in collider, timeMs); + TriggerCollide(ref ball, ref state, in collider); return true; } return false; } - private static void TriggerCollide(ref BallData ball, ref PhysicsState state, in Collider collider, uint timeMs) + private static void TriggerCollide(ref BallData ball, ref PhysicsState state, in Collider collider) { ref var triggerState = ref state.GetTriggerState(collider.Id); TriggerCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref state.InsideOfs, ref triggerState.Animation, in collider); @@ -168,7 +168,7 @@ private static void TriggerCollide(ref BallData ball, ref PhysicsState state, in if (triggerState.Animation.UnHitEvent) { ref var flipperCorrectionBlob = ref triggerState.FlipperCorrection.Value.Value; ref var fs = ref state.FlipperStates.GetValueByRef(flipperCorrectionBlob.FlipperItemId); - FlipperCorrection.OnBallLeaveFlipper(ref ball, ref flipperCorrectionBlob, in fs.Movement, in fs.Tricks, in fs.Static, timeMs); + FlipperCorrection.OnBallLeaveFlipper(ref ball, ref flipperCorrectionBlob, in fs.Movement, in fs.Tricks, in fs.Static, state.Env.TimeMsec); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index 58e11bbfe..1a27d8bae 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -17,11 +17,14 @@ // ReSharper disable ForCanBeConvertedToForeach using Unity.Collections; +using Unity.Profiling; namespace VisualPinball.Unity { public static class PhysicsStaticNarrowPhase { + private static readonly ProfilerMarker PerfMarkerNarrowPhase = new("NarrowPhase"); + internal static void FindNextCollision( float hitTime, ref BallData ball, @@ -30,6 +33,8 @@ internal static void FindNextCollision( ref PhysicsState state ) { + PerfMarkerNarrowPhase.Begin(); + // init contacts and event ball.CollisionEvent.ClearCollider(hitTime); // search upto current hit time @@ -49,6 +54,7 @@ ref PhysicsState state if (ball.CollisionEvent.HitTime < 0) { ball.CollisionEvent.ClearCollider(); } + PerfMarkerNarrowPhase.End(); } private static float HitTest(ref BallData ball, in Collider collider, ref NativeList contacts) @@ -65,7 +71,7 @@ private static void SaveCollisions(ref BallData ball, ref CollisionEventData new var validHit = newTime >= 0f && !Math.Sign(newTime) && newTime <= ball.CollisionEvent.HitTime; if (newCollEvent.IsContact || validHit) { // todo why newCollEvent.IsContact? it's not in vpx source - newCollEvent.SetCollider(colliderId, ball.Id); + newCollEvent.SetCollider(colliderId); newCollEvent.HitTime = newTime; if (newCollEvent.IsContact) { // remember all contacts? contacts.Add(new ContactBufferElement(ball.Id, newCollEvent)); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs index 7d1093987..991de491a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs @@ -52,6 +52,7 @@ internal struct PhysicsUpdateJob : IJob public NativeParallelHashMap SurfaceStates; public NativeParallelHashMap TriggerStates; public NativeParallelHashSet DisabledCollisionItems; + public bool SwapBallCollisionHandling; public void Execute() { @@ -59,12 +60,12 @@ public void Execute() var state = new PhysicsState(ref env, ref Octree, ref Colliders, ref Events, ref InsideOfs, ref Balls, ref BumperStates, ref DropTargetStates, ref FlipperStates, ref GateStates, ref HitTargetStates, ref KickerStates, ref PlungerStates, ref SpinnerStates, - ref SurfaceStates, ref TriggerStates, ref DisabledCollisionItems); + ref SurfaceStates, ref TriggerStates, ref DisabledCollisionItems, ref SwapBallCollisionHandling); var cycle = new PhysicsCycle(Allocator.Temp); while (env.CurPhysicsFrameTime < InitialTimeUsec) // loop here until current (real) time matches the physics (simulated) time { - var timeMsec = (uint)((env.CurPhysicsFrameTime - env.StartTimeUsec) / 1000); + env.TimeMsec = (uint)((env.CurPhysicsFrameTime - env.StartTimeUsec) / 1000); var physicsDiffTime = (float)((env.NextPhysicsFrameTime - env.CurPhysicsFrameTime) * (1.0 / PhysicsConstants.DefaultStepTime)); // update velocities - always on integral physics frame boundary (spinner, gate, flipper, plunger, ball) @@ -107,7 +108,7 @@ public void Execute() #endregion // primary physics loop - cycle.Simulate(ref state, in PlayfieldBounds, ref OverlappingColliders, physicsDiffTime, timeMsec); + cycle.Simulate(ref state, in PlayfieldBounds, ref OverlappingColliders, physicsDiffTime); // ball trail, keep old pos of balls using (var enumerator = state.Balls.GetEnumerator()) { @@ -135,7 +136,7 @@ public void Execute() using (var enumerator = DropTargetStates.GetEnumerator()) { while (enumerator.MoveNext()) { ref var dropTargetState = ref enumerator.Current.Value; - DropTargetAnimation.Update(enumerator.Current.Key, ref dropTargetState.Animation, in dropTargetState.Static, ref state, timeMsec); + DropTargetAnimation.Update(enumerator.Current.Key, ref dropTargetState.Animation, in dropTargetState.Static, ref state); } } @@ -143,7 +144,7 @@ public void Execute() using (var enumerator = HitTargetStates.GetEnumerator()) { while (enumerator.MoveNext()) { ref var hitTargetState = ref enumerator.Current.Value; - HitTargetAnimation.Update(ref hitTargetState.Animation, in hitTargetState.Static, timeMsec); + HitTargetAnimation.Update(ref hitTargetState.Animation, in hitTargetState.Static, env.TimeMsec); } } @@ -167,7 +168,6 @@ public void Execute() env.CurPhysicsFrameTime = env.NextPhysicsFrameTime; env.NextPhysicsFrameTime += PhysicsConstants.PhysicsStepTime; - env.TimeMsec = timeMsec; } PhysicsEnv[0] = env; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs index 4d0a4fc53..410ee093e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs @@ -32,10 +32,10 @@ internal struct CollisionEventData : IComponentData public int ColliderId; public int BallId; - public void SetCollider(int colliderId, int ballId = 0) + public void SetCollider(int colliderId) { ColliderId = colliderId; - BallId = ballId; + BallId = 0; } public void SetBallItem(int ballId) @@ -47,8 +47,7 @@ public void SetBallItem(int ballId) public void ClearCollider(float hitTime) { HitTime = hitTime; - ColliderId = -1; - BallId = 0; + ClearCollider(); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs index 10e0db32b..df95bfdec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs @@ -22,11 +22,11 @@ namespace VisualPinballUnity internal static class DropTargetAnimation { internal static void Update(int itemId, ref DropTargetAnimationData data, in DropTargetStaticData staticData, - ref PhysicsState state, uint timeMsec) + ref PhysicsState state) { - var oldTimeMsec = data.TimeMsec < timeMsec ? data.TimeMsec : timeMsec; - data.TimeMsec = timeMsec; - var diffTimeMsec = (float)(timeMsec - oldTimeMsec); + var oldTimeMsec = data.TimeMsec < state.Env.TimeMsec ? data.TimeMsec : state.Env.TimeMsec; + data.TimeMsec = state.Env.TimeMsec; + var diffTimeMsec = (float)(state.Env.TimeMsec - oldTimeMsec); if (data.HitEvent) { if (!data.IsDropped) { From a60c5108be9b09e4051d811b3717d32d0a4c2888 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 14:01:19 +0200 Subject: [PATCH 101/159] fix: Project building. --- .../VisualPinball.Unity/VPT/ColliderComponent.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index 61d19c105..cb571ce7b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -108,7 +108,9 @@ protected PhysicsMaterialData GetPhysicsMaterialData(float elasticity = 1f, floa }; } - #if UNITY_EDITOR + #region Collider Gizmos + +#if UNITY_EDITOR private void OnDrawGizmos() { @@ -196,8 +198,6 @@ private void OnDrawGizmos() Profiler.EndSample(); } - #region Collider Gizmos - private Mesh GenerateColliderMesh(ref ColliderReference colliders) { var color = Color.green; @@ -436,6 +436,8 @@ private static void DrawAabb(Aabb aabb, bool isSelected) Gizmos.DrawWireCube(aabb.Center, aabb.Size); } +#endif + #endregion void ICollidableComponent.GetColliders(Player player, ref ColliderReference colliders, float margin) @@ -444,7 +446,7 @@ void ICollidableComponent.GetColliders(Player player, ref ColliderReference coll } int ICollidableComponent.ItemId => MainComponent.gameObject.GetInstanceID(); bool ICollidableComponent.IsCollidable => isActiveAndEnabled; -#endif + } internal static class ColliderColor From 5881aaf47cb3d2693bfe3e6fe62cfacb045de144 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 15:44:35 +0200 Subject: [PATCH 102/159] project: Include com.bartofzo.nativetrees dependency. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 250dbf804..db2a575cf 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "unityRelease": "0f1", "dependencies": { "com.unity.entities": "1.0.16", + "com.bartofzo.nativetrees": "0.1.6", "com.unity.formats.fbx": "4.1.2", "com.unity.inputsystem": "1.3.0", "com.unity.ugui": "1.0.0", From 6ff201a7c8e7f96182865198f09906aa0873a14e Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 15:52:56 +0200 Subject: [PATCH 103/159] ci: Fix test dependencies. --- .../TestProject~/Packages/manifest.json | 16 +- .../TestProject~/Packages/packages-lock.json | 181 ++++++++---------- .../EntitiesClientSettings.asset | 16 ++ .../ProjectSettings/MemorySettings.asset | 35 ++++ .../PackageManagerSettings.asset | 33 ++-- .../ProjectSettings/ProjectVersion.txt | 4 +- 6 files changed, 167 insertions(+), 118 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/EntitiesClientSettings.asset create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/MemorySettings.asset diff --git a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Packages/manifest.json b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Packages/manifest.json index f86ab9853..1dc52f55f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Packages/manifest.json +++ b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Packages/manifest.json @@ -1,7 +1,9 @@ { "dependencies": { - "com.unity.test-framework": "1.1.31", - "com.unity.testtools.codecoverage": "1.1.0", + "com.unity.ai.navigation": "1.1.5", + "com.unity.test-framework": "1.1.33", + "com.unity.testtools.codecoverage": "1.2.4", + "com.unity.toolchain.win-x86_64-linux-x86_64": "2.0.6", "com.unity.ugui": "1.0.0", "org.visualpinball.engine.unity": "file:../../../..", "com.unity.modules.ai": "1.0.0", @@ -36,5 +38,13 @@ "com.unity.modules.wind": "1.0.0", "com.unity.modules.xr": "1.0.0" }, - "scopedRegistries": [] + "scopedRegistries": [ + { + "name": "VPE Registry", + "url": "https://registry.visualpinball.org", + "scopes": [ + "com.bartofzo" + ] + } + ] } diff --git a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Packages/packages-lock.json b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Packages/packages-lock.json index 54df0a3d5..b8e220bc6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Packages/packages-lock.json +++ b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Packages/packages-lock.json @@ -1,47 +1,67 @@ { "dependencies": { "com.autodesk.fbx": { - "version": "4.1.1", + "version": "4.2.1", "depth": 2, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" }, - "com.unity.burst": { - "version": "1.6.5", + "com.bartofzo.nativetrees": { + "version": "0.1.6", "depth": 1, "source": "registry", + "dependencies": { + "com.unity.burst": "1.8.9", + "com.unity.collections": "2.1.4" + }, + "url": "https://registry.visualpinball.org" + }, + "com.unity.ai.navigation": { + "version": "1.1.5", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.modules.ai": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.burst": { + "version": "1.8.9", + "depth": 2, + "source": "registry", "dependencies": { "com.unity.mathematics": "1.2.1" }, "url": "https://packages.unity.com" }, "com.unity.collections": { - "version": "0.15.0-preview.21", + "version": "2.1.4", "depth": 2, "source": "registry", "dependencies": { - "com.unity.test-framework.performance": "2.3.1-preview", - "com.unity.burst": "1.4.1" + "com.unity.burst": "1.8.4", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.nuget.mono-cecil": "1.11.4" }, "url": "https://packages.unity.com" }, "com.unity.entities": { - "version": "0.17.0-preview.42", + "version": "1.0.16", "depth": 1, "source": "registry", "dependencies": { - "com.unity.burst": "1.4.1", - "com.unity.properties": "1.5.0-preview", - "com.unity.serialization": "1.5.0-preview", - "com.unity.collections": "0.15.0-preview.21", - "com.unity.mathematics": "1.2.1", + "com.unity.burst": "1.8.8", + "com.unity.serialization": "3.1.1", + "com.unity.collections": "2.1.4", + "com.unity.mathematics": "1.2.6", "com.unity.modules.assetbundle": "1.0.0", - "com.unity.test-framework.performance": "2.3.1-preview", - "com.unity.nuget.mono-cecil": "0.1.6-preview.2", - "com.unity.jobs": "0.8.0-preview.23", - "com.unity.scriptablebuildpipeline": "1.9.0", - "com.unity.platforms": "0.10.0-preview.10" + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.test-framework.performance": "3.0.2", + "com.unity.nuget.mono-cecil": "1.11.4", + "com.unity.scriptablebuildpipeline": "1.20.2", + "com.unity.profiling.core": "1.0.2" }, "url": "https://packages.unity.com" }, @@ -53,17 +73,17 @@ "url": "https://packages.unity.com" }, "com.unity.formats.fbx": { - "version": "4.1.2", + "version": "4.2.1", "depth": 1, "source": "registry", "dependencies": { - "com.unity.timeline": "1.5.2", - "com.autodesk.fbx": "4.1.1" + "com.unity.timeline": "1.7.1", + "com.autodesk.fbx": "4.2.1" }, "url": "https://packages.unity.com" }, "com.unity.inputsystem": { - "version": "1.3.0", + "version": "1.7.0", "depth": 1, "source": "registry", "dependencies": { @@ -71,99 +91,69 @@ }, "url": "https://packages.unity.com" }, - "com.unity.jobs": { - "version": "0.8.0-preview.23", - "depth": 1, - "source": "registry", - "dependencies": { - "com.unity.collections": "0.15.0-preview.21", - "com.unity.mathematics": "1.2.1" - }, - "url": "https://packages.unity.com" - }, "com.unity.mathematics": { - "version": "1.2.5", - "depth": 1, + "version": "1.2.6", + "depth": 2, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" }, "com.unity.nuget.mono-cecil": { - "version": "1.10.1", + "version": "1.11.4", "depth": 2, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" }, - "com.unity.nuget.newtonsoft-json": { - "version": "2.0.0", - "depth": 3, + "com.unity.profiling.core": { + "version": "1.0.2", + "depth": 2, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" }, - "com.unity.platforms": { - "version": "0.10.0-preview.10", + "com.unity.scriptablebuildpipeline": { + "version": "1.21.20", "depth": 2, "source": "registry", - "dependencies": { - "com.unity.properties": "1.6.0-preview", - "com.unity.properties.ui": "1.6.2-preview.1", - "com.unity.scriptablebuildpipeline": "1.6.4-preview", - "com.unity.serialization": "1.6.2-preview" - }, + "dependencies": {}, "url": "https://packages.unity.com" }, - "com.unity.properties": { - "version": "1.6.0-preview", - "depth": 3, + "com.unity.serialization": { + "version": "3.1.1", + "depth": 2, "source": "registry", "dependencies": { - "com.unity.nuget.mono-cecil": "0.1.6-preview.2", - "com.unity.test-framework.performance": "2.3.1-preview" + "com.unity.collections": "2.1.4", + "com.unity.burst": "1.7.2" }, "url": "https://packages.unity.com" }, - "com.unity.properties.ui": { - "version": "1.6.2-preview.1", - "depth": 3, + "com.unity.settings-manager": { + "version": "2.0.1", + "depth": 1, "source": "registry", - "dependencies": { - "com.unity.properties": "1.6.0-preview", - "com.unity.serialization": "1.6.1-preview", - "com.unity.modules.uielements": "1.0.0" - }, + "dependencies": {}, "url": "https://packages.unity.com" }, - "com.unity.scriptablebuildpipeline": { - "version": "1.19.6", - "depth": 2, + "com.unity.sysroot": { + "version": "2.0.7", + "depth": 1, "source": "registry", "dependencies": {}, "url": "https://packages.unity.com" }, - "com.unity.serialization": { - "version": "1.6.2-preview", - "depth": 3, + "com.unity.sysroot.linux-x86_64": { + "version": "2.0.6", + "depth": 1, "source": "registry", "dependencies": { - "com.unity.collections": "0.12.0-preview.13", - "com.unity.burst": "1.3.5", - "com.unity.jobs": "0.5.0-preview.14", - "com.unity.properties": "1.6.0-preview", - "com.unity.test-framework.performance": "2.3.1-preview" + "com.unity.sysroot": "2.0.7" }, "url": "https://packages.unity.com" }, - "com.unity.settings-manager": { - "version": "1.0.3", - "depth": 1, - "source": "registry", - "dependencies": {}, - "url": "https://packages.unity.com" - }, "com.unity.test-framework": { - "version": "1.1.31", + "version": "1.1.33", "depth": 0, "source": "registry", "dependencies": { @@ -174,17 +164,17 @@ "url": "https://packages.unity.com" }, "com.unity.test-framework.performance": { - "version": "2.3.1-preview", + "version": "3.0.2", "depth": 2, "source": "registry", "dependencies": { - "com.unity.test-framework": "1.1.0", - "com.unity.nuget.newtonsoft-json": "2.0.0-preview" + "com.unity.test-framework": "1.1.31", + "com.unity.modules.jsonserialize": "1.0.0" }, "url": "https://packages.unity.com" }, "com.unity.testtools.codecoverage": { - "version": "1.1.0", + "version": "1.2.4", "depth": 0, "source": "registry", "dependencies": { @@ -194,7 +184,7 @@ "url": "https://packages.unity.com" }, "com.unity.timeline": { - "version": "1.6.4", + "version": "1.7.5", "depth": 2, "source": "registry", "dependencies": { @@ -205,6 +195,16 @@ }, "url": "https://packages.unity.com" }, + "com.unity.toolchain.win-x86_64-linux-x86_64": { + "version": "2.0.6", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.sysroot": "2.0.7", + "com.unity.sysroot.linux-x86_64": "2.0.6" + }, + "url": "https://packages.unity.com" + }, "com.unity.ugui": { "version": "1.0.0", "depth": 0, @@ -219,11 +219,9 @@ "depth": 0, "source": "local", "dependencies": { - "com.unity.burst": "1.6.5", - "com.unity.entities": "0.17.0-preview.42", + "com.unity.entities": "1.0.16", + "com.bartofzo.nativetrees": "0.1.6", "com.unity.formats.fbx": "4.1.2", - "com.unity.jobs": "0.8.0-preview.23", - "com.unity.mathematics": "1.2.5", "com.unity.inputsystem": "1.3.0", "com.unity.ugui": "1.0.0", "com.unity.test-framework": "1.1.31" @@ -361,17 +359,6 @@ "version": "1.0.0", "depth": 0, "source": "builtin", - "dependencies": { - "com.unity.modules.ui": "1.0.0", - "com.unity.modules.imgui": "1.0.0", - "com.unity.modules.jsonserialize": "1.0.0", - "com.unity.modules.uielementsnative": "1.0.0" - } - }, - "com.unity.modules.uielementsnative": { - "version": "1.0.0", - "depth": 1, - "source": "builtin", "dependencies": { "com.unity.modules.ui": "1.0.0", "com.unity.modules.imgui": "1.0.0", diff --git a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/EntitiesClientSettings.asset b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/EntitiesClientSettings.asset new file mode 100644 index 000000000..3f1b7c49f --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/EntitiesClientSettings.asset @@ -0,0 +1,16 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 53 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: e2ea235c1fcfe29488ed97c467a0da53, type: 3} + m_Name: + m_EditorClassIdentifier: + FilterSettings: + ExcludedBakingSystemAssemblies: [] diff --git a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/MemorySettings.asset b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/MemorySettings.asset new file mode 100644 index 000000000..5b5faceca --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/MemorySettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!387306366 &1 +MemorySettings: + m_ObjectHideFlags: 0 + m_EditorMemorySettings: + m_MainAllocatorBlockSize: -1 + m_ThreadAllocatorBlockSize: -1 + m_MainGfxBlockSize: -1 + m_ThreadGfxBlockSize: -1 + m_CacheBlockSize: -1 + m_TypetreeBlockSize: -1 + m_ProfilerBlockSize: -1 + m_ProfilerEditorBlockSize: -1 + m_BucketAllocatorGranularity: -1 + m_BucketAllocatorBucketsCount: -1 + m_BucketAllocatorBlockSize: -1 + m_BucketAllocatorBlockCount: -1 + m_ProfilerBucketAllocatorGranularity: -1 + m_ProfilerBucketAllocatorBucketsCount: -1 + m_ProfilerBucketAllocatorBlockSize: -1 + m_ProfilerBucketAllocatorBlockCount: -1 + m_TempAllocatorSizeMain: -1 + m_JobTempAllocatorBlockSize: -1 + m_BackgroundJobTempAllocatorBlockSize: -1 + m_JobTempAllocatorReducedBlockSize: -1 + m_TempAllocatorSizeGIBakingWorker: -1 + m_TempAllocatorSizeNavMeshWorker: -1 + m_TempAllocatorSizeAudioWorker: -1 + m_TempAllocatorSizeCloudWorker: -1 + m_TempAllocatorSizeGfx: -1 + m_TempAllocatorSizeJobWorker: -1 + m_TempAllocatorSizeBackgroundWorker: -1 + m_TempAllocatorSizePreloadManager: -1 + m_PlatformMemorySettings: {} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/PackageManagerSettings.asset b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/PackageManagerSettings.asset index be4a7974e..08d580056 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/PackageManagerSettings.asset +++ b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/PackageManagerSettings.asset @@ -12,10 +12,11 @@ MonoBehaviour: m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} m_Name: m_EditorClassIdentifier: - m_EnablePreviewPackages: 0 - m_EnablePackageDependencies: 0 + m_EnablePreReleasePackages: 0 m_AdvancedSettingsExpanded: 1 m_ScopedRegistriesSettingsExpanded: 1 + m_SeeAllPackageVersions: 0 + m_DismissPreviewPackagesInUse: 0 oneTimeWarningShown: 0 m_Registries: - m_Id: main @@ -24,20 +25,20 @@ MonoBehaviour: m_Scopes: [] m_IsDefault: 1 m_Capabilities: 7 - m_UserSelectedRegistryName: + m_ConfigSource: 0 + - m_Id: scoped:project:VPE Registry + m_Name: VPE Registry + m_Url: https://registry.visualpinball.org + m_Scopes: + - com.bartofzo + m_IsDefault: 0 + m_Capabilities: 0 + m_ConfigSource: 4 + m_UserSelectedRegistryName: VPE Registry m_UserAddingNewScopedRegistry: 0 m_RegistryInfoDraft: - m_ErrorMessage: - m_Original: - m_Id: - m_Name: - m_Url: - m_Scopes: [] - m_IsDefault: 0 - m_Capabilities: 0 m_Modified: 0 - m_Name: - m_Url: - m_Scopes: - - - m_SelectedScopeIndex: 0 + m_ErrorMessage: + m_UserModificationsInstanceId: -854 + m_OriginalInstanceId: -856 + m_LoadAssets: 0 diff --git a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/ProjectVersion.txt b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/ProjectVersion.txt index 6b2c79b80..37f39b7bb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/ProjectVersion.txt +++ b/VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 2021.3.0f1 -m_EditorVersionWithRevision: 2021.3.0f1 (6eacc8284459) +m_EditorVersion: 2022.3.11f1 +m_EditorVersionWithRevision: 2022.3.11f1 (d00248457e15) From eaef074a9185d88b9c56ffef1424c983d65d144f Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 16:19:01 +0200 Subject: [PATCH 104/159] jobs: Add missing apply flippertime. --- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index a14614448..282e1c4fe 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -47,7 +47,7 @@ internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref Nati var hitTime = dTime; // begin time search from now ... until delta ends - // todo apply flipper time + ApplyFlipperTime(ref hitTime, ref state); // clear contacts _contacts.Clear(); @@ -175,6 +175,22 @@ private static void ApplyStaticTime(ref float hitTime, ref float staticCounts, i } } + private void ApplyFlipperTime(ref float hitTime, ref PhysicsState state) + { + // for each flipper + using (var enumerator = state.FlipperStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + ref var flipperState = ref enumerator.Current.Value; + var flipperHitTime = flipperState.Movement.GetHitTime(flipperState.Static.AngleStart, flipperState.Tricks.AngleEnd); + + // if flipper comes to a rest before the end of the cycle, advance to that time + if (flipperHitTime > 0 && flipperHitTime < hitTime) { //!! >= 0.f causes infinite loop + hitTime = flipperHitTime; + } + } + } + } + public void Dispose() { _contacts.Dispose(); From ab75cc8c52307bb8790912bcccce4cac8a5749de Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 16:24:23 +0200 Subject: [PATCH 105/159] refactor: ball and bumper states. --- .../Game/BallRollerComponent.cs | 18 +++--- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 2 +- .../Game/PhysicsDynamicBroadPhase.cs | 4 +- .../Game/PhysicsDynamicCollision.cs | 2 +- .../Game/PhysicsDynamicNarrowPhase.cs | 2 +- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 4 +- .../VisualPinball.Unity/Game/PhysicsState.cs | 6 +- .../Game/PhysicsStaticBroadPhase.cs | 2 +- .../Game/PhysicsStaticCollision.cs | 8 +-- .../Game/PhysicsStaticNarrowPhase.cs | 6 +- .../Game/PhysicsUpdateJob.cs | 2 +- .../Physics/Collider/CircleCollider.cs | 6 +- .../Physics/Collider/Collider.cs | 24 ++++---- .../Physics/Collider/Line3DCollider.cs | 6 +- .../Physics/Collider/LineCollider.cs | 10 ++-- .../Physics/Collider/LineSlingshotCollider.cs | 6 +- .../Physics/Collider/LineZCollider.cs | 6 +- .../Physics/Collider/PlaneCollider.cs | 4 +- .../Physics/Collider/PointCollider.cs | 4 +- .../Physics/Collider/TriangleCollider.cs | 4 +- .../Physics/Collision/ContactSystem.cs | 2 +- .../Physics/Collision/KdNode.cs | 2 +- .../Physics/Collision/KdRoot.cs | 2 +- .../Physics/Collision/QuadTree.cs | 2 +- .../VPT/Ball/BallCollider.cs | 16 +++--- .../VPT/Ball/BallComponent.cs | 2 +- .../VPT/Ball/BallDisplacementPhysics.cs | 2 +- .../VPT/Ball/BallMovementPhysics.cs | 2 +- .../VPT/Ball/BallRingCounterPhysics.cs | 2 +- .../VPT/Ball/BallSpinHackPhysics.cs | 2 +- .../VPT/Ball/{BallData.cs => BallState.cs} | 7 +-- .../{BallData.cs.meta => BallState.cs.meta} | 22 ++++---- .../VPT/Ball/BallVelocityPhysics.cs | 2 +- .../VPT/Bumper/BumperCollider.cs | 16 +++--- .../VPT/Bumper/BumperComponent.cs | 6 +- .../VPT/Bumper/BumperRingAnimation.cs | 34 +++++------ ...ionData.cs => BumperRingAnimationState.cs} | 2 +- ....meta => BumperRingAnimationState.cs.meta} | 22 ++++---- .../VPT/Bumper/BumperSkirtAnimation.cs | 56 +++++++++---------- ...onData.cs => BumperSkirtAnimationState.cs} | 2 +- ...meta => BumperSkirtAnimationState.cs.meta} | 22 ++++---- .../VPT/Bumper/BumperState.cs | 10 ++-- ...mperStaticData.cs => BumperStaticState.cs} | 2 +- ...Data.cs.meta => BumperStaticState.cs.meta} | 22 ++++---- .../VPT/Bumper/BumperTransform.cs | 10 ++-- .../VPT/Flipper/FlipperCollider.cs | 18 +++--- .../VPT/Flipper/FlipperCorrection.cs | 8 +-- .../VPT/Gate/GateCollider.cs | 4 +- .../VPT/HitTarget/TargetCollider.cs | 4 +- .../VPT/Kicker/KickerApi.cs | 2 +- .../VPT/Kicker/KickerCollider.cs | 6 +- .../VPT/Plunger/PlungerCollider.cs | 4 +- .../VPT/Spinner/SpinnerCollider.cs | 4 +- .../VPT/Trigger/TriggerCollider.cs | 2 +- 54 files changed, 223 insertions(+), 224 deletions(-) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/{BallData.cs => BallState.cs} (93%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/{BallData.cs.meta => BallState.cs.meta} (95%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperRingAnimationData.cs => BumperRingAnimationState.cs} (92%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperRingAnimationData.cs.meta => BumperRingAnimationState.cs.meta} (95%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperSkirtAnimationData.cs => BumperSkirtAnimationState.cs} (92%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperSkirtAnimationData.cs.meta => BumperSkirtAnimationState.cs.meta} (95%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperStaticData.cs => BumperStaticState.cs} (93%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/{BumperStaticData.cs.meta => BumperStaticState.cs.meta} (95%) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs index 436b94824..5a7837c0d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs @@ -48,7 +48,7 @@ private void Awake() _playfieldPlane.Set3Points(p1, p2, p3); _entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - _ballEntityQuery = _entityManager.CreateEntityQuery(typeof(BallData)); + _ballEntityQuery = _entityManager.CreateEntityQuery(typeof(BallState)); } private void Update() @@ -62,10 +62,10 @@ private void Update() if (GetCursorPositionOnPlayfield(out var mousePosition)) { var ballEntities = _ballEntityQuery.ToEntityArray(Allocator.Temp); var nearestDistance = float.PositiveInfinity; - BallData nearestBall = default; + BallState nearestBall = default; var ballFound = false; foreach (var ballEntity in ballEntities) { - var ballData = _entityManager.GetComponentData(ballEntity); + var ballData = _entityManager.GetComponentData(ballEntity); if (ballData.IsFrozen) { continue; } @@ -85,24 +85,24 @@ private void Update() } else if (Mouse.current.middleButton.isPressed && _ballEntity != Entity.Null) { if (GetCursorPositionOnPlayfield(out var mousePosition)) { - var ballData = _entityManager.GetComponentData(_ballEntity); + var ballData = _entityManager.GetComponentData(_ballEntity); UpdateBall(ref ballData, mousePosition); } } if (Mouse.current.middleButton.wasReleasedThisFrame && _ballEntity != Entity.Null) { - var ballData = _entityManager.GetComponentData(_ballEntity); + var ballData = _entityManager.GetComponentData(_ballEntity); ballData.ManualControl = false; _entityManager.SetComponentData(_ballEntity, ballData); _ballEntity = Entity.Null; } } - private void UpdateBall(ref BallData ballData, float2 position) + private void UpdateBall(ref BallState ballState, float2 position) { - ballData.ManualControl = true; - ballData.ManualPosition = position; - _entityManager.SetComponentData(_ballEntity, ballData); + ballState.ManualControl = true; + ballState.ManualPosition = position; + _entityManager.SetComponentData(_ballEntity, ballState); } private bool GetCursorPositionOnPlayfield(out float2 position) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 282e1c4fe..49fee3154 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -160,7 +160,7 @@ internal void Simulate(ref PhysicsState state, in AABB playfieldBounds, ref Nati PerfMarker.End(); } - private static void ApplyStaticTime(ref float hitTime, ref float staticCounts, in BallData ball) + private static void ApplyStaticTime(ref float hitTime, ref float staticCounts, in BallState ball) { // for each collision event var collEvent = ball.CollisionEvent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs index 053f9a0b1..ffa298ccb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicBroadPhase.cs @@ -26,7 +26,7 @@ public static class PhysicsDynamicBroadPhase private static readonly ProfilerMarker PerfMarkerBallOctree = new("CreateBallOctree"); private static readonly ProfilerMarker PerfMarkerDynamicBroadPhase = new("DynamicBroadPhase"); - internal static NativeOctree CreateOctree(ref NativeParallelHashMap balls, in AABB playfieldBounds) + internal static NativeOctree CreateOctree(ref NativeParallelHashMap balls, in AABB playfieldBounds) { PerfMarkerBallOctree.Begin(); var octree = new NativeOctree(playfieldBounds, 16, 10, Allocator.TempJob); @@ -39,7 +39,7 @@ internal static NativeOctree CreateOctree(ref NativeParallelHashMap octree, in BallData ball, ref NativeParallelHashSet overlappingBalls, ref NativeParallelHashMap balls) + internal static void FindOverlaps(in NativeOctree octree, in BallState ball, ref NativeParallelHashSet overlappingBalls, ref NativeParallelHashMap balls) { PerfMarkerDynamicBroadPhase.Begin(); overlappingBalls.Clear(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs index 5c872c88e..553e4fab6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicCollision.cs @@ -23,7 +23,7 @@ internal static class PhysicsDynamicCollision { private static readonly ProfilerMarker PerfMarker = new("DynamicCollision"); - internal static void Collide(float hitTime, ref BallData ball, ref PhysicsState state) + internal static void Collide(float hitTime, ref BallState ball, ref PhysicsState state) { // pick "other" ball ref var collEvent = ref ball.CollisionEvent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs index 46d5adc42..05a25fb3f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsDynamicNarrowPhase.cs @@ -24,7 +24,7 @@ internal static class PhysicsDynamicNarrowPhase { private static readonly ProfilerMarker PerfMarkerDynamicNarrowPhase = new("DynamicNarrowPhase"); - internal static void FindNextCollision(ref BallData ball, ref NativeParallelHashSet collidingBalls, + internal static void FindNextCollision(ref BallState ball, ref NativeParallelHashSet collidingBalls, ref NativeList contacts, ref PhysicsState state) { // don't play with frozen balls diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 928e191ee..09efab71c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -40,7 +40,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private NativeArray _physicsEnv = new(1, Allocator.Persistent); [NonSerialized] private NativeQueue _eventQueue = new(Allocator.Persistent); - [NonSerialized] private NativeParallelHashMap _ballStates = new(0, Allocator.Persistent); + [NonSerialized] private NativeParallelHashMap _ballStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _bumperStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _flipperStates = new(0, Allocator.Persistent); [NonSerialized] private NativeParallelHashMap _gateStates = new(0, Allocator.Persistent); @@ -83,7 +83,7 @@ public void ScheduleAction(uint timeoutMs, Action action) internal delegate void InputAction(ref PhysicsState state); internal void Schedule(InputAction action) => _inputActions.Enqueue(action); - internal ref BallData BallState(int itemId) => ref _ballStates.GetValueByRef(itemId); + internal ref BallState BallState(int itemId) => ref _ballStates.GetValueByRef(itemId); internal ref BumperState BumperState(int itemId) => ref _bumperStates.GetValueByRef(itemId); internal ref FlipperState FlipperState(int itemId) => ref _flipperStates.GetValueByRef(itemId); internal ref GateState GateState(int itemId) => ref _gateStates.GetValueByRef(itemId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index d71c06fd1..3b832d353 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -29,7 +29,7 @@ internal struct PhysicsState internal BlobAssetReference Colliders; internal NativeQueue.ParallelWriter EventQueue; internal InsideOfs InsideOfs; - internal NativeParallelHashMap Balls; + internal NativeParallelHashMap Balls; internal NativeParallelHashMap BumperStates; internal NativeParallelHashMap DropTargetStates; internal NativeParallelHashMap FlipperStates; @@ -44,7 +44,7 @@ internal struct PhysicsState internal bool SwapBallCollisionHandling; public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAssetReference colliders, - ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeParallelHashMap balls, + ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeParallelHashMap balls, ref NativeParallelHashMap bumperStates, ref NativeParallelHashMap dropTargetStates, ref NativeParallelHashMap flipperStates, ref NativeParallelHashMap gateStates, ref NativeParallelHashMap hitTargetStates, ref NativeParallelHashMap kickerStates, @@ -158,7 +158,7 @@ internal ref SurfaceState GetSurfaceState(int colliderId) #region Hit Test - internal float HitTest(int colliderId, ref BallData ball, ref CollisionEventData collEvent, ref NativeList contacts, ref PhysicsState state) + internal float HitTest(int colliderId, ref BallState ball, ref CollisionEventData collEvent, ref NativeList contacts, ref PhysicsState state) { if (IsInactiveDropTarget(colliderId)) { return -1f; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs index 57a8079ac..2e7d7dcdf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticBroadPhase.cs @@ -24,7 +24,7 @@ public static class PhysicsStaticBroadPhase { private static readonly ProfilerMarker PerfMarkerBroadPhase = new("BroadPhase"); - internal static void FindOverlaps(in NativeOctree octree, in BallData ball, ref NativeParallelHashSet overlappingColliders) + internal static void FindOverlaps(in NativeOctree octree, in BallState ball, ref NativeParallelHashSet overlappingColliders) { PerfMarkerBroadPhase.Begin(); overlappingColliders.Clear(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 042ab6af3..5e27eedef 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -23,7 +23,7 @@ namespace VisualPinball.Unity { internal static class PhysicsStaticCollision { - internal static void Collide(float hitTime, ref BallData ball, ref PhysicsState state) + internal static void Collide(float hitTime, ref BallState ball, ref PhysicsState state) { // find balls with hit objects and minimum time @@ -37,7 +37,7 @@ internal static void Collide(float hitTime, ref BallData ball, ref PhysicsState ball.CollisionEvent.ClearCollider(); } - private static void Collide(ref BallData ball, ref PhysicsState state) + private static void Collide(ref BallState ball, ref PhysicsState state) { var colliderId = ball.CollisionEvent.ColliderId; var collider = state.GetCollider(colliderId); @@ -128,7 +128,7 @@ private static void Collide(ref BallData ball, ref PhysicsState state) } } - private static bool CollidesWithItem(ref Collider collider, ref BallData ball, ref PhysicsState state) + private static bool CollidesWithItem(ref Collider collider, ref BallState ball, ref PhysicsState state) { // hit target var colliderId = ball.CollisionEvent.ColliderId; @@ -159,7 +159,7 @@ private static bool CollidesWithItem(ref Collider collider, ref BallData ball, r return false; } - private static void TriggerCollide(ref BallData ball, ref PhysicsState state, in Collider collider) + private static void TriggerCollide(ref BallState ball, ref PhysicsState state, in Collider collider) { ref var triggerState = ref state.GetTriggerState(collider.Id); TriggerCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref state.InsideOfs, ref triggerState.Animation, in collider); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index 1a27d8bae..ffc28b026 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -27,7 +27,7 @@ public static class PhysicsStaticNarrowPhase internal static void FindNextCollision( float hitTime, - ref BallData ball, + ref BallState ball, ref NativeParallelHashSet overlappingColliders, ref NativeList contacts, ref PhysicsState state @@ -57,7 +57,7 @@ ref PhysicsState state PerfMarkerNarrowPhase.End(); } - private static float HitTest(ref BallData ball, in Collider collider, ref NativeList contacts) + private static float HitTest(ref BallState ball, in Collider collider, ref NativeList contacts) { ref var collEvent = ref ball.CollisionEvent; var hitTime = Collider.HitTest(in collider, ref collEvent, in ball, ball.CollisionEvent.HitTime); @@ -65,7 +65,7 @@ private static float HitTest(ref BallData ball, in Collider collider, ref Native return hitTime; } - private static void SaveCollisions(ref BallData ball, ref CollisionEventData newCollEvent, + private static void SaveCollisions(ref BallState ball, ref CollisionEventData newCollEvent, ref NativeList contacts, int colliderId, float newTime) { var validHit = newTime >= 0f && !Math.Sign(newTime) && newTime <= ball.CollisionEvent.HitTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs index 991de491a..4b77a37cf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs @@ -40,7 +40,7 @@ internal struct PhysicsUpdateJob : IJob public NativeQueue.ParallelWriter Events; public AABB PlayfieldBounds; - public NativeParallelHashMap Balls; + public NativeParallelHashMap Balls; public NativeParallelHashMap BumperStates; public NativeParallelHashMap DropTargetStates; public NativeParallelHashMap FlipperStates; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs index 8f2940720..f4024fd65 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs @@ -68,13 +68,13 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray insideOf, in BallData ball, float dTime) + ref DynamicBuffer insideOf, in BallState ball, float dTime) { fixed (Collider* collider = &coll) { @@ -126,7 +126,7 @@ internal static unsafe float HitTest(ref Collider coll, ref CollisionEventData c } } - internal static unsafe float HitTest(in Collider coll, ref CollisionEventData collEvent, in BallData ball, float dTime) + internal static unsafe float HitTest(in Collider coll, ref CollisionEventData collEvent, in BallState ball, float dTime) { fixed (Collider* collider = &coll) { @@ -174,7 +174,7 @@ internal static unsafe float HitTest(in Collider coll, ref CollisionEventData co /// Most colliders use the standard Collide3DWall routine, only overrides /// are cast and dispatched to their respective implementation. /// - internal static unsafe void Collide(in Collider coll, ref BallData ballData, + internal static unsafe void Collide(in Collider coll, ref BallState ballState, ref NativeQueue.ParallelWriter events, in int ballId, in CollisionEventData collEvent, ref Random random) { @@ -183,25 +183,25 @@ internal static unsafe void Collide(in Collider coll, ref BallData ballData, switch (collider->Type) { case ColliderType.Circle: - ((CircleCollider*) collider)->Collide(ref ballData, in collEvent, ref random); + ((CircleCollider*) collider)->Collide(ref ballState, in collEvent, ref random); break; case ColliderType.Line: - ((LineCollider*) collider)->Collide(ref ballData, ref events, in ballId, in collEvent, ref random); + ((LineCollider*) collider)->Collide(ref ballState, ref events, in ballId, in collEvent, ref random); break; case ColliderType.Line3D: - ((Line3DCollider*) collider)->Collide(ref ballData, ref events, in ballId, in collEvent, ref random); + ((Line3DCollider*) collider)->Collide(ref ballState, ref events, in ballId, in collEvent, ref random); break; case ColliderType.LineZ: - ((LineZCollider*) collider)->Collide(ref ballData, ref events, in ballId, in collEvent, ref random); + ((LineZCollider*) collider)->Collide(ref ballState, ref events, in ballId, in collEvent, ref random); break; case ColliderType.Plane: - ((PlaneCollider*) collider)->Collide(ref ballData, in collEvent, ref random); + ((PlaneCollider*) collider)->Collide(ref ballState, in collEvent, ref random); break; case ColliderType.Point: - ((PointCollider*) collider)->Collide(ref ballData, ref events, in ballId, in collEvent, ref random); + ((PointCollider*) collider)->Collide(ref ballState, ref events, in ballId, in collEvent, ref random); break; case ColliderType.Triangle: - ((TriangleCollider*) collider)->Collide(ref ballData, ref events, in ballId, in collEvent, ref random); + ((TriangleCollider*) collider)->Collide(ref ballState, ref events, in ballId, in collEvent, ref random); break; default: @@ -210,7 +210,7 @@ internal static unsafe void Collide(in Collider coll, ref BallData ballData, } } - internal static void FireHitEvent(ref BallData ball, ref NativeQueue.ParallelWriter events, in ColliderHeader collHeader) + internal static void FireHitEvent(ref BallState ball, ref NativeQueue.ParallelWriter events, in ColliderHeader collHeader) { if (collHeader.FireEvents/* && collHeader.IsEnabled*/) { // todo enabled @@ -231,7 +231,7 @@ internal static void FireHitEvent(ref BallData ball, ref NativeQueue. } } - internal static void Contact(ref Collider coll, ref BallData ball, in CollisionEventData collEvent, double hitTime, in float3 gravity) + internal static void Contact(ref Collider coll, ref BallState ball, in CollisionEventData collEvent, double hitTime, in float3 gravity) { BallCollider.HandleStaticContact(ref ball, in collEvent, coll.Header.Material.Friction, (float)hitTime, gravity); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs index 8846702ae..bd6f37c77 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs @@ -100,12 +100,12 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray.ParallelWriter hitEvents, + public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index 28a484dc7..954a1e4b2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -92,24 +92,24 @@ public void CalcNormal() #region Narrowphase public static float HitTest(ref CollisionEventData collEvent, - ref InsideOfs insideOfs, in LineCollider coll, in BallData ball, float dTime) + ref InsideOfs insideOfs, in LineCollider coll, in BallState ball, float dTime) { return HitTestBasic(ref collEvent, ref insideOfs, in coll, in ball, dTime, true, true, true); // normal face, lateral, rigid } public float HitTest(ref CollisionEventData collEvent, - ref InsideOfs insideOfs, in BallData ball, float dTime) + ref InsideOfs insideOfs, in BallState ball, float dTime) { return HitTestBasic(ref collEvent, ref insideOfs, in this, in ball, dTime, true, true, true); // normal face, lateral, rigid } - public float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallData ball, float dTime, + public float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallState ball, float dTime, bool direction, bool lateral, bool rigid) { return HitTestBasic(ref collEvent, ref insideOfs, in this, in ball, dTime, direction, lateral, rigid); } - public static float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in LineCollider coll, in BallData ball, float dTime, bool direction, bool lateral, bool rigid) + public static float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in LineCollider coll, in BallState ball, float dTime, bool direction, bool lateral, bool rigid) { // ball velocity var ballVx = ball.Velocity.x; @@ -229,7 +229,7 @@ public static float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs #region Collision - public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, + public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs index dd46f8f97..c40c020a9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs @@ -83,12 +83,12 @@ private void CalcNormal() #region Narrowphase - public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallData ball, float dTime) + public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallState ball, float dTime) { return HitTest(ref collEvent, ref this, ref insideOfs, in ball, dTime); } - private static float HitTest(ref CollisionEventData collEvent, ref LineSlingshotCollider coll, ref InsideOfs insideOfs, in BallData ball, float dTime) + private static float HitTest(ref CollisionEventData collEvent, ref LineSlingshotCollider coll, ref InsideOfs insideOfs, in BallState ball, float dTime) { ref var lineColl = ref UnsafeUtility.As(ref coll); return LineCollider.HitTestBasic(ref collEvent, ref insideOfs, in lineColl, in ball, dTime, true, true, true); @@ -98,7 +98,7 @@ private static float HitTest(ref CollisionEventData collEvent, ref LineSlingshot #region Collision - public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, in LineSlingshotData slingshotData, in CollisionEventData collEvent, ref Random random) + public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, in LineSlingshotData slingshotData, in CollisionEventData collEvent, ref Random random) { var hitNormal = collEvent.HitNormal; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs index 48918581c..88861b2b6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs @@ -65,12 +65,12 @@ public LineZCollider(float2 xy, float zLow, float zHigh, ColliderInfo info) : th #region Narrowphase - public float HitTest(ref CollisionEventData collEvent, in BallData ball, float dTime) + public float HitTest(ref CollisionEventData collEvent, in BallState ball, float dTime) { return HitTest(ref collEvent, in this, in ball, dTime); } - public static float HitTest(ref CollisionEventData collEvent, in LineZCollider coll, in BallData ball, float dTime) + public static float HitTest(ref CollisionEventData collEvent, in LineZCollider coll, in BallState ball, float dTime) { // todo // if (!IsEnabled) { @@ -164,7 +164,7 @@ public static float HitTest(ref CollisionEventData collEvent, in LineZCollider c #region Collision - public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, + public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index 7e620997a..c438038fc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -59,7 +59,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray.ParallelWriter hitEvents, + public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs index 9ba097415..7d1a6a350 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs @@ -82,7 +82,7 @@ public static bool IsDegenerate(float3 rg0, float3 rg1, float3 rg2) #region Narrowphase - public float HitTest(ref CollisionEventData collEvent, in InsideOfs insideOfs, in BallData ball, float dTime) + public float HitTest(ref CollisionEventData collEvent, in InsideOfs insideOfs, in BallState ball, float dTime) { // if (!this.isEnabled) { // return -1.0; @@ -179,7 +179,7 @@ public float HitTest(ref CollisionEventData collEvent, in InsideOfs insideOfs, i #region Collision - public void Collide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, + public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = -math.dot(collEvent.HitNormal, ball.Velocity); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs index db3c39dcf..b724da2bf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs @@ -20,7 +20,7 @@ namespace VisualPinballUnity { internal static class ContactPhysics { - internal static void Update(ref ContactBufferElement contact, ref BallData ball, ref PhysicsState state, float hitTime) + internal static void Update(ref ContactBufferElement contact, ref BallState ball, ref PhysicsState state, float hitTime) { ref var collEvent = ref contact.CollEvent; if (collEvent.ColliderId > -1) { // collide with static collider diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs index 8d97efcb4..eb7e3917d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs @@ -276,7 +276,7 @@ public void CreateNextLevel(int level, int levelEmpty, KdRoot hitOct) { childB.CreateNextLevel(level + 1, levelEmpty, hitOct); } - public void GetAabbOverlaps(ref KdRoot hitOct, in Entity entity, in BallData ball, ref DynamicBuffer overlappingEntities) { + public void GetAabbOverlaps(ref KdRoot hitOct, in Entity entity, in BallState ball, ref DynamicBuffer overlappingEntities) { var orgItems = Items & 0x3FFFFFFF; var axis = Items >> 30; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs index 059b20b79..466ca9454 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs @@ -62,7 +62,7 @@ private void FillFromVector(NativeArray bounds) _rootNode.CreateNextLevel(0, 0, this); } - public void GetAabbOverlaps(in Entity entity, in BallData ball, ref DynamicBuffer overlappingEntities) + public void GetAabbOverlaps(in Entity entity, in BallState ball, ref DynamicBuffer overlappingEntities) { _rootNode.GetAabbOverlaps(ref this, in entity, in ball, ref overlappingEntities); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs index 01102fce8..46c5618b3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs @@ -191,7 +191,7 @@ private static Aabb GetBounds(int i, in float3 center, in Aabb bounds) }; } - public void GetAabbOverlaps(in BallData ball, in NativeHashMap itemsColliding, ref DynamicBuffer matchedColliderIds) + public void GetAabbOverlaps(in BallState ball, in NativeHashMap itemsColliding, ref DynamicBuffer matchedColliderIds) { var ballAabb = ball.Aabb; var collisionRadiusSqr = ball.CollisionRadiusSqr; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallCollider.cs index 68a6cfffe..e3b4fd091 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallCollider.cs @@ -24,7 +24,7 @@ internal static class BallCollider { private const float HardScatter = 0.0f; - public static void Collide3DWall(ref BallData ball, in PhysicsMaterialData material, in CollisionEventData collEvent, in float3 hitNormal, ref Random random) + public static void Collide3DWall(ref BallState ball, in PhysicsMaterialData material, in CollisionEventData collEvent, in float3 hitNormal, ref Random random) { // speed normal to wall var dot = math.dot(ball.Velocity, hitNormal); @@ -78,7 +78,7 @@ public static void Collide3DWall(ref BallData ball, in PhysicsMaterialData mater // compute friction impulse var surfP = -ball.Radius * hitNormal; // surface contact point relative to center of mass - var surfVel = BallData.SurfaceVelocity(in ball, in surfP); // velocity at impact point + var surfVel = BallState.SurfaceVelocity(in ball, in surfP); // velocity at impact point var tangent = surfVel - hitNormal * math.dot(surfVel, hitNormal); // calc the tangential velocity var tangentSpSq = math.lengthsq(tangent); @@ -139,7 +139,7 @@ public static void Collide3DWall(ref BallData ball, in PhysicsMaterialData mater } } - public static void HandleStaticContact(ref BallData ball, in CollisionEventData collEvent, float friction, float dTime, in float3 gravity) + public static void HandleStaticContact(ref BallState ball, in CollisionEventData collEvent, float friction, float dTime, in float3 gravity) { // this should be zero, but only up to +/- PhysicsConstants.ContactVel var normVel = math.dot(ball.Velocity, collEvent.HitNormal); @@ -161,11 +161,11 @@ public static void HandleStaticContact(ref BallData ball, in CollisionEventData } } - private static void ApplyFriction(ref BallData ball, in float3 hitNormal, float dTime, float frictionCoeff, in float3 gravity) + private static void ApplyFriction(ref BallState ball, in float3 hitNormal, float dTime, float frictionCoeff, in float3 gravity) { // surface contact point relative to center of mass var surfP = -ball.Radius * hitNormal; - var surfVel = BallData.SurfaceVelocity(in ball, in surfP); + var surfVel = BallState.SurfaceVelocity(in ball, in surfP); // calc the tangential slip velocity var slip = surfVel - hitNormal * math.dot(surfVel, hitNormal); @@ -181,7 +181,7 @@ private static void ApplyFriction(ref BallData ball, in float3 hitNormal, float // check for <=0.025 originated from ball<->rubber collisions pushing the ball upwards, but this is still not enough, some could even use <=0.2 // slip speed zero - static friction case - var surfAcc = BallData.SurfaceAcceleration(in ball, in surfP, in gravity); + var surfAcc = BallState.SurfaceAcceleration(in ball, in surfP, in gravity); // calc the tangential slip acceleration var slipAcc = surfAcc - hitNormal * math.dot(surfAcc, hitNormal); @@ -208,7 +208,7 @@ private static void ApplyFriction(ref BallData ball, in float3 hitNormal, float } } - public static float HitTest(ref CollisionEventData collEvent, ref BallData otherBall, in BallData ball, float dTime) + public static float HitTest(ref CollisionEventData collEvent, ref BallState otherBall, in BallState ball, float dTime) { var d = ball.Position - otherBall.Position; // delta position var dv = ball.Velocity - otherBall.Velocity; // delta velocity @@ -305,7 +305,7 @@ public static float HitTest(ref CollisionEventData collEvent, ref BallData other return hitTime; } - public static bool Collide(ref BallData ball, ref BallData otherBall, + public static bool Collide(ref BallState ball, ref BallState otherBall, in CollisionEventData ballCollEvent, in CollisionEventData otherCollEvent, bool swapBallCollisionHandling) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs index 76aed330e..986045f62 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs @@ -30,7 +30,7 @@ public class BallComponent : MonoBehaviour public bool IsFrozen; - internal BallData CreateState() => new BallData { + internal BallState CreateState() => new BallState { Id = Id, IsFrozen = IsFrozen, Position = transform.localPosition.TranslateToVpx(), diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs index a4c1f20c9..3a4810081 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs @@ -22,7 +22,7 @@ namespace VisualPinballUnity { internal static class BallDisplacementPhysics { - internal static void UpdateDisplacements(ref BallData ball, float dTime) + internal static void UpdateDisplacements(ref BallState ball, float dTime) { if (ball.IsFrozen) { return; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs index aeea4e2cc..f309490b1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs @@ -37,7 +37,7 @@ internal static class BallMovementPhysics // _player = Object.FindObjectOfType(); // } - public static void Move(BallData ball, Transform ballTransform) + public static void Move(BallState ball, Transform ballTransform) { // calculate/adapt height of ball var zHeight = !ball.IsFrozen ? ball.Position.z : ball.Position.z - ball.Radius; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterPhysics.cs index f8146f2c8..00c84dc16 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallRingCounterPhysics.cs @@ -20,7 +20,7 @@ namespace VisualPinball.Unity { internal static class BallRingCounterPhysics { - internal static void Update(ref BallData ball) + internal static void Update(ref BallState ball) { var idx = ball.RingCounterOldPos / (10000 / PhysicsConstants.PhysicsStepTime); ball.LastPositions[idx] = ball.Position; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs index 64fe0eb99..c3a490e29 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs @@ -26,7 +26,7 @@ namespace VisualPinballUnity [DisableAutoCreation] internal static class BallSpinHackPhysics { - internal static void Update(ref BallData ball) + internal static void Update(ref BallState ball) { var p0 = (ball.RingCounterOldPos / (10000 / PhysicsConstants.PhysicsStepTime) + 1) % BallPositions.Count; var p1 = (ball.RingCounterOldPos / (10000 / PhysicsConstants.PhysicsStepTime) + 2) % BallPositions.Count; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallState.cs similarity index 93% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallState.cs index 56843bf7f..95fcfdc5e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallState.cs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using NativeTrees; using Unity.Entities; using Unity.Mathematics; using VisualPinballUnity; @@ -22,7 +21,7 @@ namespace VisualPinball.Unity { // todo split this into at least 2 components - internal struct BallData : IComponentData + internal struct BallState : IComponentData { public int Id; public float3 Position; @@ -114,7 +113,7 @@ public void ApplySurfaceImpulse(in float3 rotI, in float3 impulse) AngularMomentum += rotI; } - public static float3 SurfaceVelocity(in BallData ball, in float3 surfP) + public static float3 SurfaceVelocity(in BallState ball, in float3 surfP) { // linear velocity plus tangential velocity due to rotation return ball.Velocity + math.cross(ball.AngularMomentum / ball.Inertia, surfP); @@ -132,7 +131,7 @@ Original code from VPX */ } - public static float3 SurfaceAcceleration(in BallData ball, in float3 surfP, in float3 gravity) + public static float3 SurfaceAcceleration(in BallState ball, in float3 surfP, in float3 gravity) { var currentAngularVelocity = ball.AngularMomentum / ball.Inertia; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallState.cs.meta similarity index 95% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallState.cs.meta index fc73b3430..e4990103a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallData.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallState.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 40e389a41e9b61d419678ddd9a131c51 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 40e389a41e9b61d419678ddd9a131c51 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs index 3e077ad8b..6beae0b93 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs @@ -24,7 +24,7 @@ namespace VisualPinballUnity { internal static class BallVelocityPhysics { - public static void UpdateVelocities(ref BallData ball, float3 gravity) + public static void UpdateVelocities(ref BallState ball, float3 gravity) { if (ball.IsFrozen) { return; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs index f5832f36e..663179bf2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs @@ -22,9 +22,9 @@ namespace VisualPinball.Unity { internal static class BumperCollider { - public static void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, - ref CollisionEventData collEvent, ref BumperRingAnimationData ringData, ref BumperSkirtAnimationData skirtData, - in Collider collider, in BumperStaticData data, ref Random random) + public static void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, + ref CollisionEventData collEvent, ref BumperRingAnimationState ringState, ref BumperSkirtAnimationState skirtState, + in Collider collider, in BumperStaticState state, ref Random random) { // todo // if (!m_enabled) return; @@ -33,13 +33,13 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle var material = collider.Material; BallCollider.Collide3DWall(ref ball, in material, in collEvent, in collEvent.HitNormal, ref random); // reflect ball from wall - if (data.HitEvent && dot <= -data.Threshold) { // if velocity greater than threshold level + if (state.HitEvent && dot <= -state.Threshold) { // if velocity greater than threshold level - ball.Velocity += collEvent.HitNormal * data.Force; // add a chunk of velocity to drive ball away + ball.Velocity += collEvent.HitNormal * state.Force; // add a chunk of velocity to drive ball away - ringData.IsHit = true; - skirtData.HitEvent = true; - skirtData.BallPosition = ball.Position; + ringState.IsHit = true; + skirtState.HitEvent = true; + skirtState.BallPosition = ball.Position; events.Enqueue(new EventData(EventId.HitEventsHit, collider.ItemId, ball.Id, true)); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs index 1da2039b7..3eb309359 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs @@ -306,7 +306,7 @@ internal BumperState CreateState() // physics collision data var collComponent = GetComponentInChildren(); var staticData = collComponent - ? new BumperStaticData { + ? new BumperStaticState { Force = collComponent.Force, HitEvent = collComponent.HitEvent, Threshold = collComponent.Threshold @@ -315,7 +315,7 @@ internal BumperState CreateState() // skirt animation data var skirtAnimComponent = GetComponentInChildren(); var skirtAnimation = skirtAnimComponent - ? new BumperSkirtAnimationData { + ? new BumperSkirtAnimationState { BallPosition = default, AnimationCounter = 0f, DoAnimate = false, @@ -328,7 +328,7 @@ internal BumperState CreateState() // ring animation data var ringAnimComponent = GetComponentInChildren(); var ringAnimation = ringAnimComponent - ? new BumperRingAnimationData { + ? new BumperRingAnimationState { // dynamic IsHit = false, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimation.cs index 1ccbd4d61..0dc629b8b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimation.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimation.cs @@ -18,31 +18,31 @@ namespace VisualPinball.Unity { internal static class BumperRingAnimation { - internal static void Update(ref BumperRingAnimationData data, float dTime) + internal static void Update(ref BumperRingAnimationState state, float dTime) { // todo visibility - skip if invisible - var limit = data.DropOffset + data.HeightScale * 0.5f; - if (data.IsHit) { - data.DoAnimate = true; - data.AnimateDown = true; - data.IsHit = false; + var limit = state.DropOffset + state.HeightScale * 0.5f; + if (state.IsHit) { + state.DoAnimate = true; + state.AnimateDown = true; + state.IsHit = false; } - if (data.DoAnimate) { - var step = data.Speed; - if (data.AnimateDown) { + if (state.DoAnimate) { + var step = state.Speed; + if (state.AnimateDown) { step = -step; } - data.Offset += step * dTime; - if (data.AnimateDown) { - if (data.Offset <= -limit) { - data.Offset = -limit; - data.AnimateDown = false; + state.Offset += step * dTime; + if (state.AnimateDown) { + if (state.Offset <= -limit) { + state.Offset = -limit; + state.AnimateDown = false; } } else { - if (data.Offset >= 0.0f) { - data.Offset = 0.0f; - data.DoAnimate = false; + if (state.Offset >= 0.0f) { + state.Offset = 0.0f; + state.DoAnimate = false; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationState.cs similarity index 92% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationState.cs index fd02a86f1..af9f11efc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct BumperRingAnimationData + internal struct BumperRingAnimationState { public bool IsHit; public float DropOffset; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationState.cs.meta similarity index 95% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationState.cs.meta index 94d637600..1e1d856e5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationData.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperRingAnimationState.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: f247ceaae40d7224281f631a0fb7901c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: f247ceaae40d7224281f631a0fb7901c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimation.cs index 7dd959838..3e331db4a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimation.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimation.cs @@ -20,59 +20,59 @@ namespace VisualPinball.Unity { internal static class BumperSkirtAnimation { - internal static void Update(ref BumperSkirtAnimationData data, float dTime) + internal static void Update(ref BumperSkirtAnimationState state, float dTime) { // todo visibility - skip if invisible - var isHit = data.HitEvent; - data.HitEvent = false; + var isHit = state.HitEvent; + state.HitEvent = false; - if (data.EnableAnimation) { + if (state.EnableAnimation) { if (isHit) { - data.DoAnimate = true; - UpdateSkirt(ref data); - data.AnimationCounter = 0.0f; + state.DoAnimate = true; + UpdateSkirt(ref state); + state.AnimationCounter = 0.0f; } - if (data.DoAnimate) { - data.AnimationCounter += dTime; - if (data.AnimationCounter > 160.0f) { - data.DoAnimate = false; - ResetSkirt(ref data); + if (state.DoAnimate) { + state.AnimationCounter += dTime; + if (state.AnimationCounter > 160.0f) { + state.DoAnimate = false; + ResetSkirt(ref state); } } - } else if (data.DoUpdate) { // do a single update if the animation was turned off via script - data.DoUpdate = false; - ResetSkirt(ref data); + } else if (state.DoUpdate) { // do a single update if the animation was turned off via script + state.DoUpdate = false; + ResetSkirt(ref state); } } - private static void UpdateSkirt(ref BumperSkirtAnimationData data) + private static void UpdateSkirt(ref BumperSkirtAnimationState state) { const float skirtTilt = 5.0f; - var hitX = data.BallPosition.x; - var hitY = data.BallPosition.y; - var dy = math.abs(hitY - data.Center.y); + var hitX = state.BallPosition.x; + var hitY = state.BallPosition.y; + var dy = math.abs(hitY - state.Center.y); if (dy == 0.0f) { dy = 0.000001f; } - var dx = math.abs(hitX - data.Center.x); + var dx = math.abs(hitX - state.Center.x); var skirtA = math.atan(dx / dy); - data.Rotation.x = math.cos(skirtA) * skirtTilt; - data.Rotation.y = math.sin(skirtA) * skirtTilt; - if (data.Center.y < hitY) { - data.Rotation.x = -data.Rotation.x; + state.Rotation.x = math.cos(skirtA) * skirtTilt; + state.Rotation.y = math.sin(skirtA) * skirtTilt; + if (state.Center.y < hitY) { + state.Rotation.x = -state.Rotation.x; } - if (data.Center.x > hitX) { - data.Rotation.y = -data.Rotation.y; + if (state.Center.x > hitX) { + state.Rotation.y = -state.Rotation.y; } } - private static void ResetSkirt(ref BumperSkirtAnimationData data) + private static void ResetSkirt(ref BumperSkirtAnimationState state) { - data.Rotation = new float2(0, 0); + state.Rotation = new float2(0, 0); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationState.cs similarity index 92% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationState.cs index 0f64ae026..f61274231 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationState.cs @@ -18,7 +18,7 @@ namespace VisualPinball.Unity { - internal struct BumperSkirtAnimationData + internal struct BumperSkirtAnimationState { // dynamic public bool HitEvent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationState.cs.meta similarity index 95% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationState.cs.meta index 4d8f62fd4..56fcb823b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationData.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperSkirtAnimationState.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 763cf045db0d0444b9ba0b9c074711e3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 763cf045db0d0444b9ba0b9c074711e3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs index 6ecbdf3c3..1e2de8b9f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperState.cs @@ -21,12 +21,12 @@ internal struct BumperState internal readonly int ItemId; internal readonly int SkirtItemId; internal int RingItemId; - internal BumperStaticData Static; - internal BumperRingAnimationData RingAnimation; - internal BumperSkirtAnimationData SkirtAnimation; + internal BumperStaticState Static; + internal BumperRingAnimationState RingAnimation; + internal BumperSkirtAnimationState SkirtAnimation; - public BumperState(int itemId, int skirtItemId, int ringItemId, BumperStaticData @static, - BumperRingAnimationData ringAnimation, BumperSkirtAnimationData skirtAnimation) + public BumperState(int itemId, int skirtItemId, int ringItemId, BumperStaticState @static, + BumperRingAnimationState ringAnimation, BumperSkirtAnimationState skirtAnimation) { ItemId = itemId; SkirtItemId = skirtItemId; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticState.cs similarity index 93% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticState.cs index 9b7f255fc..e992caa22 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct BumperStaticData + internal struct BumperStaticState { public float Force; public float Threshold; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticState.cs.meta similarity index 95% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticState.cs.meta index 677faf6d7..aecfefd22 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticData.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperStaticState.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 7e0c88d47ab1257499977c31f15fb37b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 7e0c88d47ab1257499977c31f15fb37b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransform.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransform.cs index db36deacb..62f84f244 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransform.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperTransform.cs @@ -26,23 +26,23 @@ internal static class BumperTransform { private static readonly Dictionary InitialOffset = new(); - internal static void UpdateRing(int itemId, in BumperRingAnimationData data, Transform transform) + internal static void UpdateRing(int itemId, in BumperRingAnimationState state, Transform transform) { var worldPos = transform.position; InitialOffset.TryAdd(itemId, worldPos.y); - var limit = data.DropOffset + data.HeightScale * 0.5f; + var limit = state.DropOffset + state.HeightScale * 0.5f; var localLimit = InitialOffset[itemId] + limit; - var localOffset = localLimit / limit * data.Offset; + var localOffset = localLimit / limit * state.Offset; worldPos.y = InitialOffset[itemId] + Physics.ScaleToWorld(localOffset); transform.position = worldPos; } - internal static void UpdateSkirt(in BumperSkirtAnimationData data, Transform transform) + internal static void UpdateSkirt(in BumperSkirtAnimationState state, Transform transform) { var parentRotation = transform.parent.rotation; - transform.rotation = Quaternion.Euler(data.Rotation.x, 0, -data.Rotation.y) * parentRotation; + transform.rotation = Quaternion.Euler(state.Rotation.x, 0, -state.Rotation.y) * parentRotation; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs index c7bfb7577..6964e0bc2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs @@ -153,7 +153,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray.ParallelWriter events, in int ballId, in FlipperTricksData tricks, in FlipperStaticData matData, in FlipperVelocityData velData, in FlipperHitData hitData, uint timeMsec) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs index dc3edaaa7..d5404be1d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { internal static class FlipperCorrection { - public static void OnBallLeaveFlipper(ref BallData ballData, ref FlipperCorrectionBlob flipperCorrectionBlob, + public static void OnBallLeaveFlipper(ref BallState ballState, ref FlipperCorrectionBlob flipperCorrectionBlob, in FlipperMovementData flipperMovementData, in FlipperTricksData tricks, in FlipperStaticData flipperStaticData, uint timeMs) { @@ -35,8 +35,8 @@ public static void OnBallLeaveFlipper(ref BallData ballData, ref FlipperCorrecti ref var polarities = ref flipperCorrectionBlob.Polarities; var angleCur = flipperMovementData.Angle; - var ballPosition = ballData.Position; - var ballVelocity = ballData.Velocity; + var ballPosition = ballState.Position; + var ballVelocity = ballState.Velocity; var uncorrectedVel = ballVelocity; if (ballVelocity.y > -8F) // ball going down { @@ -85,7 +85,7 @@ public static void OnBallLeaveFlipper(ref BallData ballData, ref FlipperCorrecti // Apply all corrections - ballData.Velocity = ballVelocity; + ballState.Velocity = ballVelocity; } // awful linear interpolations : TODO: replace by AnimationCurve equivalent... diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs index 8a0dd3542..2b11dd2c5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs @@ -58,7 +58,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray.ParallelWriter events, in Collider coll, in GateStaticData data) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs index 58ab0b8f7..0e9c2b177 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity { internal static class TargetCollider { - public static void DropTargetCollide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, + public static void DropTargetCollide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, ref DropTargetAnimationData animationData, in float3 normal, in CollisionEventData collEvent, in Collider coll, ref Random random) { @@ -39,7 +39,7 @@ public static void DropTargetCollide(ref BallData ball, ref NativeQueue.ParallelWriter hitEvents, + public static void HitTargetCollide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, ref HitTargetAnimationData animationData, in float3 normal, in CollisionEventData collEvent, in Collider coll, ref Random random) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs index d87caab19..3a77221e3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs @@ -116,7 +116,7 @@ public bool HasBall() return kickerState.Collision.HasBall; } - internal ref BallData GetBallData() + internal ref BallState GetBallData() { ref var kickerState = ref PhysicsEngine.KickerState(ItemId); return ref PhysicsEngine.BallState(kickerState.Collision.BallId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs index 24e13ea28..a337d0e2d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs @@ -32,7 +32,7 @@ internal static class KickerCollider /// public const bool ForceLegacyMode = false; - public static void Collide(ref BallData ball, ref NativeQueue.ParallelWriter events, + public static void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, ref InsideOfs insideOfs, ref KickerCollisionData collData, in KickerStaticData staticData, in ColliderMeshData meshData, in CollisionEventData collEvent, in int itemId) { @@ -121,7 +121,7 @@ public static void Collide(ref BallData ball, ref NativeQueue.Paralle } } - private static void DoChangeBallVelocity(ref BallData ball, in float3 hitNormal, in ColliderMeshData meshData) + private static void DoChangeBallVelocity(ref BallState ball, in float3 hitNormal, in ColliderMeshData meshData) { var minDistSqr = Constants.FloatMax; var idx = 0u; @@ -145,7 +145,7 @@ private static void DoChangeBallVelocity(ref BallData ball, in float3 hitNormal, var reactionImpulse = ball.Mass * math.abs(dot); var surfP = -ball.Radius * hitNormal; // surface contact point relative to center of mass - var surfVel = BallData.SurfaceVelocity(in ball, surfP); // velocity at impact point + var surfVel = BallState.SurfaceVelocity(in ball, surfP); // velocity at impact point var tangent = surfVel - math.dot(surfVel, hitNormal) * hitNorm; // calc the tangential velocity // apply collision impulse (along normal, so no torque) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs index b9bd895ba..b03ad65b5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs @@ -78,7 +78,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray.ParallelWriter events, + public static void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, ref CollisionEventData collEvent, ref InsideOfs insideOfs, ref TriggerAnimationData animationData, in Collider coll) { From 9e804060af4a41d5598cfe7f35c1a94c88bc0e8d Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 19:10:11 +0200 Subject: [PATCH 106/159] ci: Fix Unity version during tests. --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a076fbb9b..2d8e154e0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,6 +65,7 @@ jobs: - uses: game-ci/unity-test-runner@main id: test with: + unityVersion: "2022.3.10f1" projectPath: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~ artifactsPath: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/artifacts testMode: all From afde8fd12b2a61d2063078032fd071d85aabd86d Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Sun, 15 Oct 2023 16:15:57 -0400 Subject: [PATCH 107/159] ci: request license for newer version of unity --- .github/workflows/license.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml index 3d31df94c..11ab52de0 100644 --- a/.github/workflows/license.yml +++ b/.github/workflows/license.yml @@ -10,7 +10,7 @@ jobs: id: license uses: game-ci/unity-request-activation-file@v2 with: - unityVersion: 2021.3.0f1 + unityVersion: 2022.3.11f1 - uses: actions/upload-artifact@v2 with: name: ${{ steps.license.outputs.filePath }} From 878e06390ba91896589dd6dc9bc2fe59458b6cd6 Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Sun, 15 Oct 2023 16:17:32 -0400 Subject: [PATCH 108/159] ci: request license specifically for 2022.3.10f1 --- .github/workflows/license.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml index 11ab52de0..f65555ed5 100644 --- a/.github/workflows/license.yml +++ b/.github/workflows/license.yml @@ -10,7 +10,7 @@ jobs: id: license uses: game-ci/unity-request-activation-file@v2 with: - unityVersion: 2022.3.11f1 + unityVersion: 2022.3.10f1 - uses: actions/upload-artifact@v2 with: name: ${{ steps.license.outputs.filePath }} From 56d670f7db4f5e2793c7f251f15e6c735e442f2e Mon Sep 17 00:00:00 2001 From: Jason Millard Date: Sun, 15 Oct 2023 16:46:07 -0400 Subject: [PATCH 109/159] ci: attempt to use a custom docker image for activation --- .github/workflows/license.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml index f65555ed5..67bb68ce4 100644 --- a/.github/workflows/license.yml +++ b/.github/workflows/license.yml @@ -11,6 +11,7 @@ jobs: uses: game-ci/unity-request-activation-file@v2 with: unityVersion: 2022.3.10f1 + customImage: "unityci/editor:ubuntu-2022.3.10f1-linux-il2cpp-2" - uses: actions/upload-artifact@v2 with: name: ${{ steps.license.outputs.filePath }} From e0ff36fa459b0600248e224aad256af1c0f947cd Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 20:21:44 +0200 Subject: [PATCH 110/159] refactor: Name all states as such. --- .../Physics/Collider/LineSlingshotCollider.cs | 6 +- ...SlingshotData.cs => LineSlingshotState.cs} | 2 +- ...ata.cs.meta => LineSlingshotState.cs.meta} | 0 .../VPT/Flipper/FlipperCollider.cs | 48 ++++---- .../VPT/Flipper/FlipperComponent.cs | 4 +- .../VPT/Flipper/FlipperCorrection.cs | 8 +- ...ctionData.cs => FlipperCorrectionState.cs} | 2 +- ...cs.meta => FlipperCorrectionState.cs.meta} | 0 .../VPT/Flipper/FlipperDisplacementPhysics.cs | 40 +++---- ...ovementData.cs => FlipperMovementState.cs} | 10 +- ...a.cs.meta => FlipperMovementState.cs.meta} | 22 ++-- .../VPT/Flipper/FlipperState.cs | 4 +- .../VPT/Gate/GateCollider.cs | 20 ++-- .../VPT/Gate/GateComponent.cs | 4 +- .../VPT/Gate/GateDisplacementPhysics.cs | 88 +++++++-------- ...teMovementData.cs => GateMovementState.cs} | 2 +- ...Data.cs.meta => GateMovementState.cs.meta} | 0 .../VisualPinball.Unity/VPT/Gate/GateState.cs | 6 +- .../{GateStaticData.cs => GateStaticState.cs} | 2 +- ...icData.cs.meta => GateStaticState.cs.meta} | 0 .../VPT/Gate/GateVelocityPhysics.cs | 16 +-- .../VPT/HitTarget/DropTargetAnimation.cs | 52 ++++----- ...ionData.cs => DropTargetAnimationState.cs} | 2 +- ....meta => DropTargetAnimationState.cs.meta} | 0 .../VPT/HitTarget/DropTargetComponent.cs | 8 +- .../VPT/HitTarget/DropTargetState.cs | 6 +- ...StaticData.cs => DropTargetStaticState.cs} | 2 +- ....cs.meta => DropTargetStaticState.cs.meta} | 0 .../VPT/HitTarget/TargetCollider.cs | 8 +- .../VPT/Kicker/KickerCollider.cs | 30 ++--- ...llisionData.cs => KickerCollisionState.cs} | 2 +- ...a.cs.meta => KickerCollisionState.cs.meta} | 0 .../VPT/Kicker/KickerComponent.cs | 4 +- .../VPT/Kicker/KickerState.cs | 6 +- ...ckerStaticData.cs => KickerStaticState.cs} | 2 +- ...Data.cs.meta => KickerStaticState.cs.meta} | 0 .../VPT/Plunger/PlungerAnimation.cs | 10 +- ...mationData.cs => PlungerAnimationState.cs} | 2 +- ....cs.meta => PlungerAnimationState.cs.meta} | 0 .../VPT/Plunger/PlungerCollider.cs | 32 +++--- ...olliderData.cs => PlungerColliderState.cs} | 2 +- ...a.cs.meta => PlungerColliderState.cs.meta} | 0 .../VPT/Plunger/PlungerCommands.cs | 42 +++---- .../VPT/Plunger/PlungerComponent.cs | 10 +- .../VPT/Plunger/PlungerDisplacementPhysics.cs | 88 +++++++-------- ...ovementData.cs => PlungerMovementState.cs} | 2 +- ...a.cs.meta => PlungerMovementState.cs.meta} | 0 .../VPT/Plunger/PlungerState.cs | 12 +- ...gerStaticData.cs => PlungerStaticState.cs} | 2 +- ...ata.cs.meta => PlungerStaticState.cs.meta} | 0 .../VPT/Plunger/PlungerVelocityPhysics.cs | 104 +++++++++--------- ...elocityData.cs => PlungerVelocityState.cs} | 2 +- ...a.cs.meta => PlungerVelocityState.cs.meta} | 0 .../VPT/Spinner/SpinnerCollider.cs | 12 +- .../VPT/Spinner/SpinnerComponent.cs | 4 +- .../VPT/Spinner/SpinnerDisplacementPhysics.cs | 52 ++++----- ...ovementData.cs => SpinnerMovementState.cs} | 2 +- ...a.cs.meta => SpinnerMovementState.cs.meta} | 0 .../VPT/Spinner/SpinnerState.cs | 6 +- ...nerStaticData.cs => SpinnerStaticState.cs} | 2 +- ...ata.cs.meta => SpinnerStaticState.cs.meta} | 0 .../VPT/Spinner/SpinnerVelocityPhysics.cs | 6 +- .../VPT/Surface/SurfaceComponent.cs | 2 +- .../VPT/Surface/SurfaceState.cs | 4 +- .../VPT/Trigger/TriggerAnimation.cs | 66 +++++------ ...mationData.cs => TriggerAnimationState.cs} | 2 +- ....cs.meta => TriggerAnimationState.cs.meta} | 0 .../VPT/Trigger/TriggerCollider.cs | 6 +- .../VPT/Trigger/TriggerComponent.cs | 10 +- ...ovementData.cs => TriggerMovementState.cs} | 2 +- ...a.cs.meta => TriggerMovementState.cs.meta} | 0 .../VPT/Trigger/TriggerState.cs | 12 +- ...gerStaticData.cs => TriggerStaticState.cs} | 2 +- ...ata.cs.meta => TriggerStaticState.cs.meta} | 0 .../VPT/Trigger/TriggerTransform.cs | 4 +- 75 files changed, 454 insertions(+), 454 deletions(-) rename VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/{LineSlingshotData.cs => LineSlingshotState.cs} (93%) rename VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/{LineSlingshotData.cs.meta => LineSlingshotState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/{FlipperCorrectionData.cs => FlipperCorrectionState.cs} (91%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/{FlipperCorrectionData.cs.meta => FlipperCorrectionState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/{FlipperMovementData.cs => FlipperMovementState.cs} (82%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/{FlipperMovementData.cs.meta => FlipperMovementState.cs.meta} (95%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/{GateMovementData.cs => GateMovementState.cs} (93%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/{GateMovementData.cs.meta => GateMovementState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/{GateStaticData.cs => GateStaticState.cs} (93%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/{GateStaticData.cs.meta => GateStaticState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/{DropTargetAnimationData.cs => DropTargetAnimationState.cs} (92%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/{DropTargetAnimationData.cs.meta => DropTargetAnimationState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/{DropTargetStaticData.cs => DropTargetStaticState.cs} (92%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/{DropTargetStaticData.cs.meta => DropTargetStaticState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/{KickerCollisionData.cs => KickerCollisionState.cs} (91%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/{KickerCollisionData.cs.meta => KickerCollisionState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/{KickerStaticData.cs => KickerStaticState.cs} (92%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/{KickerStaticData.cs.meta => KickerStaticState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerAnimationData.cs => PlungerAnimationState.cs} (92%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerAnimationData.cs.meta => PlungerAnimationState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerColliderData.cs => PlungerColliderState.cs} (93%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerColliderData.cs.meta => PlungerColliderState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerMovementData.cs => PlungerMovementState.cs} (97%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerMovementData.cs.meta => PlungerMovementState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerStaticData.cs => PlungerStaticState.cs} (93%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerStaticData.cs.meta => PlungerStaticState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerVelocityData.cs => PlungerVelocityState.cs} (96%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/{PlungerVelocityData.cs.meta => PlungerVelocityState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/{SpinnerMovementData.cs => SpinnerMovementState.cs} (92%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/{SpinnerMovementData.cs.meta => SpinnerMovementState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/{SpinnerStaticData.cs => SpinnerStaticState.cs} (93%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/{SpinnerStaticData.cs.meta => SpinnerStaticState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/{TriggerAnimationData.cs => TriggerAnimationState.cs} (92%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/{TriggerAnimationData.cs.meta => TriggerAnimationState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/{TriggerMovementData.cs => TriggerMovementState.cs} (92%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/{TriggerMovementData.cs.meta => TriggerMovementState.cs.meta} (100%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/{TriggerStaticData.cs => TriggerStaticState.cs} (93%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/{TriggerStaticData.cs.meta => TriggerStaticState.cs.meta} (100%) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs index c40c020a9..d21bd4e88 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs @@ -98,7 +98,7 @@ private static float HitTest(ref CollisionEventData collEvent, ref LineSlingshot #region Collision - public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, in LineSlingshotData slingshotData, in CollisionEventData collEvent, ref Random random) + public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, in LineSlingshotState slingshotState, in CollisionEventData collEvent, ref Random random) { var hitNormal = collEvent.HitNormal; @@ -106,9 +106,9 @@ public void Collide(ref BallState ball, ref NativeQueue.ParallelWrite var dot = math.dot(collEvent.HitNormal, ball.Velocity); // normal greater than threshold? - var threshold = dot <= -slingshotData.Threshold; + var threshold = dot <= -slingshotState.Threshold; - if (!slingshotData.IsDisabled && threshold) { // enabled and if velocity greater than threshold level + if (!slingshotState.IsDisabled && threshold) { // enabled and if velocity greater than threshold level // length of segment, Unit TAN points from V1 to V2 var len = (V2.x - V1.x) * hitNormal.y - (V2.y - V1.y) * hitNormal.x; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotState.cs similarity index 93% rename from VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotData.cs rename to VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotState.cs index 169624a3e..bdc3a7084 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct LineSlingshotData + internal struct LineSlingshotState { public bool IsDisabled; public float Threshold; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/LineSlingshotState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs index 6964e0bc2..fe0374dec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs @@ -153,7 +153,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray= 0) { return hitTime; } // second face - hitTime = HitTestFlipperFace(ref collEvent, ref hitData, movementData, tricks, matData, ball, dTime, !lastFace); + hitTime = HitTestFlipperFace(ref collEvent, ref hitData, movementState, tricks, matData, ball, dTime, !lastFace); if (hitTime >= 0) { hitData.LastHitFace = !lastFace; // change this face to check first // HACK return hitTime; } // end radius - hitTime = HitTestFlipperEnd(ref collEvent, ref hitData, movementData, tricks, matData, ball, dTime); + hitTime = HitTestFlipperEnd(ref collEvent, ref hitData, movementState, tricks, matData, ball, dTime); if (hitTime >= 0) { return hitTime; } @@ -200,11 +200,11 @@ public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, } private float HitTestFlipperFace(ref CollisionEventData collEvent, ref FlipperHitData hitData, - in FlipperMovementData movementData, in FlipperTricksData tricks, in FlipperStaticData matData, in BallState ball, + in FlipperMovementState movementState, in FlipperTricksData tricks, in FlipperStaticData matData, in BallState ball, float dTime, bool face1) { - var angleCur = movementData.Angle; - var angleSpeed = movementData.AngleSpeed; // rotation rate + var angleCur = movementState.Angle; + var angleSpeed = movementState.AngleSpeed; // rotation rate var flipperBase = _hitCircleBase.Center; var feRadius = matData.EndRadius; @@ -420,10 +420,10 @@ private float HitTestFlipperFace(ref CollisionEventData collEvent, ref FlipperHi } private float HitTestFlipperEnd(ref CollisionEventData collEvent, ref FlipperHitData hitData, - in FlipperMovementData movementData, in FlipperTricksData tricks, in FlipperStaticData matData, in BallState ball, float dTime) + in FlipperMovementState movementState, in FlipperTricksData tricks, in FlipperStaticData matData, in BallState ball, float dTime) { - var angleCur = movementData.Angle; - var angleSpeed = movementData.AngleSpeed; // rotation rate + var angleCur = movementState.Angle; + var angleSpeed = movementState.AngleSpeed; // rotation rate var flipperBase = _hitCircleBase.Center; @@ -617,7 +617,7 @@ private float HitTestFlipperEnd(ref CollisionEventData collEvent, ref FlipperHit #region Contact - public void Contact(ref BallState ball, ref FlipperMovementData movementData, in CollisionEventData collEvent, + public void Contact(ref BallState ball, ref FlipperMovementState movementState, in CollisionEventData collEvent, in FlipperStaticData matData, in FlipperVelocityData velData, float dTime, in float3 gravity) { var normal = collEvent.HitNormal; @@ -627,7 +627,7 @@ public void Contact(ref BallState ball, ref FlipperMovementData movementData, in ball.Velocity += 0.1f * normal; } - GetRelativeVelocity(normal, ball, in movementData, out var vRel, out var rB, out var rF); + GetRelativeVelocity(normal, ball, in movementState, out var vRel, out var rB, out var rF); // this should be zero, but only up to +/- C_CONTACTVEL var normVel = math.dot(vRel, normal); @@ -636,11 +636,11 @@ public void Contact(ref BallState ball, ref FlipperMovementData movementData, in if (normVel <= PhysicsConstants.ContactVel) { // compute accelerations of point on ball and flipper var aB = BallState.SurfaceAcceleration(in ball, in rB, in gravity); - var aF = FlipperMovementData.SurfaceAcceleration(in movementData, in velData, in rF); + var aF = FlipperMovementState.SurfaceAcceleration(in movementState, in velData, in rF); var aRel = aB - aF; // time derivative of the normal vector - var normalDeriv = Math.CrossZ(movementData.AngleSpeed, normal); + var normalDeriv = Math.CrossZ(movementState.AngleSpeed, normal); // relative acceleration in the normal direction var normAcc = math.dot(aRel, normal) + 2.0f * math.dot(normalDeriv, vRel); @@ -660,7 +660,7 @@ public void Contact(ref BallState ball, ref FlipperMovementData movementData, in // kill any existing normal velocity ball.Velocity += (j * dTime * ball.InvMass - collEvent.HitOrgNormalVelocity) * normal; - movementData.ApplyImpulse(j * dTime * cross, matData.Inertia); + movementState.ApplyImpulse(j * dTime * cross, matData.Inertia); // apply friction @@ -701,11 +701,11 @@ public void Contact(ref BallState ball, ref FlipperMovementData movementData, in var friction = math.clamp(numer / (denomB + denomF), -maxFriction, maxFriction); ball.ApplySurfaceImpulse(dTime * friction * crossB, dTime * friction * slipDir); - movementData.ApplyImpulse(-dTime * friction * crossF, matData.Inertia); + movementState.ApplyImpulse(-dTime * friction * crossF, matData.Inertia); } } - private void GetRelativeVelocity(in float3 normal, in BallState ball, in FlipperMovementData movementData, out float3 vRel, out float3 rB, out float3 rF) + private void GetRelativeVelocity(in float3 normal, in BallState ball, in FlipperMovementState movementState, out float3 vRel, out float3 rB, out float3 rF) { rB = -ball.Radius * normal; var hitPos = ball.Position + rB; @@ -718,7 +718,7 @@ private void GetRelativeVelocity(in float3 normal, in BallState ball, in Flipper rF = hitPos - cF; // displacement relative to flipper center var vB = BallState.SurfaceVelocity(in ball, in rB); - var vF = FlipperMovementData.SurfaceVelocity(in movementData, in rF); + var vF = FlipperMovementState.SurfaceVelocity(in movementState, in rF); vRel = vB - vF; } @@ -776,12 +776,12 @@ public static void LiveCatch(ref BallState ball, ref CollisionEventData collEven #region Collision - public void Collide(ref BallState ball, ref CollisionEventData collEvent, ref FlipperMovementData movementData, + public void Collide(ref BallState ball, ref CollisionEventData collEvent, ref FlipperMovementState movementState, ref NativeQueue.ParallelWriter events, in int ballId, in FlipperTricksData tricks, in FlipperStaticData matData, in FlipperVelocityData velData, in FlipperHitData hitData, uint timeMsec) { var normal = collEvent.HitNormal; - GetRelativeVelocity(normal, ball, movementData, out var vRel, out var rB, out var rF); + GetRelativeVelocity(normal, ball, movementState, out var vRel, out var rB, out var rF); var bnv = math.dot(normal, vRel); // relative normal velocity @@ -879,7 +879,7 @@ public void Collide(ref BallState ball, ref CollisionEventData collEvent, ref Fl } ball.Velocity += impulse * ball.InvMass * normal; // new velocity for ball after impact - movementData.ApplyImpulse(rotI, matData.Inertia); + movementState.ApplyImpulse(rotI, matData.Inertia); // apply friction var tangent = vRel - math.dot(vRel, normal) * normal; // calc the tangential velocity @@ -906,11 +906,11 @@ public void Collide(ref BallState ball, ref CollisionEventData collEvent, ref Fl jt * crossB, jt * tangent ); - movementData.ApplyImpulse(-jt * crossF, matData.Inertia); + movementState.ApplyImpulse(-jt * crossF, matData.Inertia); } // event - if (bnv < -0.25f && timeMsec - movementData.LastHitTime > 250) { + if (bnv < -0.25f && timeMsec - movementState.LastHitTime > 250) { // limit rate to 250 milliseconds per event var flipperHit = hitData.HitMomentBit ? -1.0f : -bnv; // move event processing to end of collision handler... if (flipperHit < 0f) { @@ -922,7 +922,7 @@ public void Collide(ref BallState ball, ref CollisionEventData collEvent, ref Fl events.Enqueue(new EventData(EventId.FlipperEventsCollide, _header.ItemId, ballId, flipperHit)); } } - movementData.LastHitTime = timeMsec; // keep resetting until idle for 250 milliseconds + movementState.LastHitTime = timeMsec; // keep resetting until idle for 250 milliseconds } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index 94b5f6c7b..d021e59a8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -594,14 +594,14 @@ internal FlipperStaticData GetMaterialData(FlipperColliderComponent colliderComp }; } - internal FlipperMovementData GetMovementData(FlipperStaticData d) + internal FlipperMovementState GetMovementData(FlipperStaticData d) { // store flipper base rotation without starting angle var baseRotation = math.normalize(math.mul( math.normalize(transform.rotation), quaternion.EulerXYZ(0, 0, -d.AngleStart) )); - return new FlipperMovementData { + return new FlipperMovementState { Angle = d.AngleStart, AngleSpeed = 0f, AngularMomentum = 0f, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs index d5404be1d..cd3f306bf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs @@ -22,10 +22,10 @@ namespace VisualPinball.Unity internal static class FlipperCorrection { public static void OnBallLeaveFlipper(ref BallState ballState, ref FlipperCorrectionBlob flipperCorrectionBlob, - in FlipperMovementData flipperMovementData, in FlipperTricksData tricks, in FlipperStaticData flipperStaticData, uint timeMs) + in FlipperMovementState flipperMovementState, in FlipperTricksData tricks, in FlipperStaticData flipperStaticData, uint timeMs) { - var timeSinceFlipperStartedRotatingToEndMs = timeMs - flipperMovementData.StartRotateToEndTime; + var timeSinceFlipperStartedRotatingToEndMs = timeMs - flipperMovementState.StartRotateToEndTime; // Time delay overrun test if (timeSinceFlipperStartedRotatingToEndMs > flipperCorrectionBlob.TimeDelayMs) @@ -33,7 +33,7 @@ public static void OnBallLeaveFlipper(ref BallState ballState, ref FlipperCorrec ref var velocities = ref flipperCorrectionBlob.Velocities; ref var polarities = ref flipperCorrectionBlob.Polarities; - var angleCur = flipperMovementData.Angle; + var angleCur = flipperMovementState.Angle; var ballPosition = ballState.Position; var ballVelocity = ballState.Velocity; @@ -43,7 +43,7 @@ public static void OnBallLeaveFlipper(ref BallState ballState, ref FlipperCorrec return; } - var angleAtFire = flipperMovementData.AngleAtRotateToEnd; + var angleAtFire = flipperMovementState.AngleAtRotateToEnd; var angleStart = flipperStaticData.AngleStart; var angleEnd = tricks.AngleEnd; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs similarity index 91% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs index f68bf3399..43e531e8d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs @@ -18,7 +18,7 @@ namespace VisualPinball.Unity { - public struct FlipperCorrectionData : IComponentData + public struct FlipperCorrectionState : IComponentData { public bool IsEnabled; public BlobAssetReference Value; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs index 0e66092a9..d3277dc82 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs @@ -23,26 +23,26 @@ namespace VisualPinballUnity { internal static class FlipperDisplacementPhysics { - internal static void UpdateDisplacement(int itemId, ref FlipperMovementData state, ref FlipperTricksData tricks, in FlipperStaticData data, + internal static void UpdateDisplacement(int itemId, ref FlipperMovementState movementState, ref FlipperTricksData tricks, in FlipperStaticData staticState, float dTime, ref NativeQueue.ParallelWriter events) { //var dTime = _simulateCycleSystemGroup.HitTime; var currentTime = 0;// todo SystemAPI.Time.ElapsedTime; - state.Angle += state.AngleSpeed * dTime; // move flipper angle + movementState.Angle += movementState.AngleSpeed * dTime; // move flipper angle - var angleMin = math.min(data.AngleStart, tricks.AngleEnd); - var angleMax = math.max(data.AngleStart, tricks.AngleEnd); + var angleMin = math.min(staticState.AngleStart, tricks.AngleEnd); + var angleMax = math.max(staticState.AngleStart, tricks.AngleEnd); - if (state.Angle > angleMax) { - state.Angle = angleMax; + if (movementState.Angle > angleMax) { + movementState.Angle = angleMax; } - if (state.Angle < angleMin) { - state.Angle = angleMin; + if (movementState.Angle < angleMin) { + movementState.Angle = angleMin; } - if (math.abs(state.AngleSpeed) < 0.0005f) { + if (math.abs(movementState.AngleSpeed) < 0.0005f) { // avoids "jumping balls" when two or more balls held on flipper (and more other balls are in play) //!! make dependent on physics update rate return; } @@ -50,39 +50,39 @@ internal static void UpdateDisplacement(int itemId, ref FlipperMovementData stat var handleEvent = false; // ReSharper disable once CompareOfFloatsByEqualityOperator - if (state.Angle == tricks.AngleEnd) { + if (movementState.Angle == tricks.AngleEnd) { tricks.FlipperAngleEndTime = currentTime; } - if (state.Angle >= angleMax) { + if (movementState.Angle >= angleMax) { // hit stop? - if (state.AngleSpeed > 0) { + if (movementState.AngleSpeed > 0) { handleEvent = true; } - } else if (state.Angle <= angleMin) { - if (state.AngleSpeed < 0) { + } else if (movementState.Angle <= angleMin) { + if (movementState.AngleSpeed < 0) { handleEvent = true; } } if (handleEvent) { - var angleSpeed = math.abs(math.degrees(state.AngleSpeed)); - state.AngularMomentum *= -0.3f; // make configurable? - state.AngleSpeed = state.AngularMomentum / data.Inertia; + var angleSpeed = math.abs(math.degrees(movementState.AngleSpeed)); + movementState.AngularMomentum *= -0.3f; // make configurable? + movementState.AngleSpeed = movementState.AngularMomentum / staticState.Inertia; - if (state.EnableRotateEvent > 0) { + if (movementState.EnableRotateEvent > 0) { // send EOS event events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, angleSpeed)); - } else if (state.EnableRotateEvent < 0) { + } else if (movementState.EnableRotateEvent < 0) { // send BOS event events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, angleSpeed)); } - state.EnableRotateEvent = 0; + movementState.EnableRotateEvent = 0; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementState.cs similarity index 82% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementState.cs index 801a02deb..db61e0709 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementState.cs @@ -19,7 +19,7 @@ namespace VisualPinball.Unity { - internal struct FlipperMovementData : IComponentData + internal struct FlipperMovementState : IComponentData { public float Angle; public float AngleSpeed; @@ -40,21 +40,21 @@ public void ApplyImpulse(in float3 rotI, float inertia) AngleSpeed = AngularMomentum / inertia; // figure TODO out moment of inertia } - public static float3 SurfaceAcceleration(in FlipperMovementData data, in FlipperVelocityData velData, in float3 surfP) + public static float3 SurfaceAcceleration(in FlipperMovementState movement, in FlipperVelocityData velData, in float3 surfP) { // tangential acceleration = (0, 0, omega) x surfP var tangAcc = Math.CrossZ(velData.AngularAcceleration, surfP); // centripetal acceleration = (0,0,omega) x ( (0,0,omega) x surfP ) - var av2 = data.AngleSpeed * data.AngleSpeed; + var av2 = movement.AngleSpeed * movement.AngleSpeed; var centrAcc = new float3(-av2 * surfP.x, -av2 * surfP.y, 0); return tangAcc + centrAcc; } - public static float3 SurfaceVelocity(in FlipperMovementData data, in float3 surfP) + public static float3 SurfaceVelocity(in FlipperMovementState movementState, in float3 surfP) { - return Math.CrossZ(data.AngleSpeed, in surfP); + return Math.CrossZ(movementState.AngleSpeed, in surfP); } public float GetHitTime(float angleStart, float angleEnd) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementState.cs.meta similarity index 95% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementState.cs.meta index b7ff39aee..0542e4811 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementData.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementState.cs.meta @@ -1,11 +1,11 @@ -fileFormatVersion: 2 -guid: 1eaedb51d635c764f85bfd3fa8bbc223 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 1eaedb51d635c764f85bfd3fa8bbc223 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs index 9ce7b80fb..087867841 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs @@ -20,13 +20,13 @@ internal struct FlipperState { internal readonly int ItemId; internal FlipperStaticData Static; - internal FlipperMovementData Movement; + internal FlipperMovementState Movement; internal FlipperVelocityData Velocity; internal FlipperHitData Hit; internal FlipperTricksData Tricks; internal SolenoidStateData Solenoid; - public FlipperState(int itemId, FlipperStaticData @static, FlipperMovementData movement, + public FlipperState(int itemId, FlipperStaticData @static, FlipperMovementState movement, FlipperVelocityData velocity, FlipperHitData hit, FlipperTricksData tricks, SolenoidStateData solenoid) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs index 2b11dd2c5..67951dbe2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs @@ -85,11 +85,11 @@ public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, #region Collision - public static void Collide(ref BallState ball, ref CollisionEventData collEvent, ref GateMovementData movementData, - ref NativeQueue.ParallelWriter events, in Collider coll, in GateStaticData data) + public static void Collide(ref BallState ball, ref CollisionEventData collEvent, ref GateMovementState movementState, + ref NativeQueue.ParallelWriter events, in Collider coll, in GateStaticState state) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); - var h = data.Height * 0.5f; + var h = state.Height * 0.5f; // linear speed = ball speed // angular speed = linear/radius (height of hit) @@ -99,19 +99,19 @@ public static void Collide(ref BallState ball, ref CollisionEventData collEvent, speed /= h; } - movementData.AngleSpeed = speed; - if (!collEvent.HitFlag && !data.TwoWay) { - movementData.HitDirection = dot > 0; - movementData.AngleSpeed *= (float)(1.0 / 8.0); // Give a little bounce-back. + movementState.AngleSpeed = speed; + if (!collEvent.HitFlag && !state.TwoWay) { + movementState.HitDirection = dot > 0; + movementState.AngleSpeed *= (float)(1.0 / 8.0); // Give a little bounce-back. return; // hit from back doesn't count if not two-way } - movementData.HitDirection = false; + movementState.HitDirection = false; // We encoded which side of the spinner the ball hit - if (collEvent.HitFlag && data.TwoWay) { + if (collEvent.HitFlag && state.TwoWay) { - movementData.AngleSpeed = -movementData.AngleSpeed; + movementState.AngleSpeed = -movementState.AngleSpeed; } Collider.FireHitEvent(ref ball, ref events, in coll.Header); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs index 5bf40fc24..ebd482a11 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs @@ -286,7 +286,7 @@ internal GateState CreateState() // collision var collComponent = GetComponent(); var staticData = collComponent - ? new GateStaticData { + ? new GateStaticState { AngleMin = math.radians(collComponent._angleMin), AngleMax = math.radians(collComponent._angleMax), Height = Position.z, @@ -298,7 +298,7 @@ internal GateState CreateState() var wireComponent = GetComponentInChildren(); var movementData = collComponent && wireComponent - ? new GateMovementData { + ? new GateMovementState { Angle = math.radians(collComponent._angleMin), AngleSpeed = 0, ForcedMove = false, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs index 88249f45c..4ce758ef7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs @@ -23,79 +23,79 @@ namespace VisualPinballUnity { internal static class GateDisplacementPhysics { - internal static void UpdateDisplacement(int itemId, ref GateMovementData movementData, in GateStaticData data, + internal static void UpdateDisplacement(int itemId, ref GateMovementState movementState, in GateStaticState state, float dTime, ref NativeQueue.ParallelWriter events) { - if (data.TwoWay) { - if (math.abs(movementData.Angle) > data.AngleMax) { - if (movementData.Angle < 0.0) { - movementData.Angle = -data.AngleMax; + if (state.TwoWay) { + if (math.abs(movementState.Angle) > state.AngleMax) { + if (movementState.Angle < 0.0) { + movementState.Angle = -state.AngleMax; } else { - movementData.Angle = data.AngleMax; + movementState.Angle = state.AngleMax; } // send EOS event - events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, movementData.AngleSpeed)); + events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, movementState.AngleSpeed)); - if (!movementData.ForcedMove) { - movementData.AngleSpeed = -movementData.AngleSpeed; - movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - } else if (movementData.AngleSpeed > 0.0) { - movementData.AngleSpeed = 0.0f; + if (!movementState.ForcedMove) { + movementState.AngleSpeed = -movementState.AngleSpeed; + movementState.AngleSpeed *= state.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + } else if (movementState.AngleSpeed > 0.0) { + movementState.AngleSpeed = 0.0f; } } - if (math.abs(movementData.Angle) < data.AngleMin) { - if (movementData.Angle < 0.0) { - movementData.Angle = -data.AngleMin; + if (math.abs(movementState.Angle) < state.AngleMin) { + if (movementState.Angle < 0.0) { + movementState.Angle = -state.AngleMin; } else { - movementData.Angle = data.AngleMin; + movementState.Angle = state.AngleMin; } - if (!movementData.ForcedMove) { - movementData.AngleSpeed = -movementData.AngleSpeed; - movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - } else if (movementData.AngleSpeed < 0.0) { - movementData.AngleSpeed = 0.0f; + if (!movementState.ForcedMove) { + movementState.AngleSpeed = -movementState.AngleSpeed; + movementState.AngleSpeed *= state.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + } else if (movementState.AngleSpeed < 0.0) { + movementState.AngleSpeed = 0.0f; } } } else { - var direction = movementData.HitDirection ? -1f : 1f; - if (direction * movementData.Angle > data.AngleMax) { - movementData.Angle = direction * data.AngleMax; + var direction = movementState.HitDirection ? -1f : 1f; + if (direction * movementState.Angle > state.AngleMax) { + movementState.Angle = direction * state.AngleMax; // send EOS event - events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, movementData.AngleSpeed)); + events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, movementState.AngleSpeed)); - if (!movementData.ForcedMove) { - movementData.AngleSpeed = -movementData.AngleSpeed; - movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - } else if (movementData.AngleSpeed > 0.0) { - movementData.AngleSpeed = 0.0f; + if (!movementState.ForcedMove) { + movementState.AngleSpeed = -movementState.AngleSpeed; + movementState.AngleSpeed *= state.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + } else if (movementState.AngleSpeed > 0.0) { + movementState.AngleSpeed = 0.0f; } } - if (direction * movementData.Angle < data.AngleMin) { - movementData.Angle = direction * data.AngleMin; + if (direction * movementState.Angle < state.AngleMin) { + movementState.Angle = direction * state.AngleMin; // send Park event - events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, movementData.AngleSpeed)); + events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, movementState.AngleSpeed)); - if (!movementData.ForcedMove) { - movementData.AngleSpeed = -movementData.AngleSpeed; - movementData.AngleSpeed *= data.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster - } else if (movementData.AngleSpeed < 0.0) { - movementData.AngleSpeed = 0.0f; + if (!movementState.ForcedMove) { + movementState.AngleSpeed = -movementState.AngleSpeed; + movementState.AngleSpeed *= state.Damping * 0.8f; // just some extra damping to reduce the angleSpeed a bit faster + } else if (movementState.AngleSpeed < 0.0) { + movementState.AngleSpeed = 0.0f; } } } - movementData.Angle += movementData.AngleSpeed * dTime; + movementState.Angle += movementState.AngleSpeed * dTime; - if (movementData.IsLifting) { - if (math.abs(movementData.Angle - movementData.LiftAngle) > 0.000001f) { - var direction = movementData.Angle < movementData.LiftAngle ? 1f : -1f; - movementData.Angle += direction * (movementData.LiftSpeed * dTime); + if (movementState.IsLifting) { + if (math.abs(movementState.Angle - movementState.LiftAngle) > 0.000001f) { + var direction = movementState.Angle < movementState.LiftAngle ? 1f : -1f; + movementState.Angle += direction * (movementState.LiftSpeed * dTime); } else { - movementData.IsLifting = false; + movementState.IsLifting = false; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementState.cs similarity index 93% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementState.cs index a80d6abe0..7af0d54bb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct GateMovementData + internal struct GateMovementState { public float Angle; public float AngleSpeed; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateMovementState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs index 0a8d46773..4e017f528 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateState.cs @@ -20,10 +20,10 @@ internal struct GateState { internal readonly int ItemId; internal readonly int WireItemId; - internal GateStaticData Static; - internal GateMovementData Movement; + internal GateStaticState Static; + internal GateMovementState Movement; - public GateState(int itemId, int wireItemId, GateStaticData @static, GateMovementData movement) + public GateState(int itemId, int wireItemId, GateStaticState @static, GateMovementState movement) { ItemId = itemId; WireItemId = wireItemId; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticState.cs similarity index 93% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticState.cs index 2c1cc728e..5f9f02b28 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct GateStaticData + internal struct GateStaticState { public float AngleMin; public float AngleMax; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateStaticState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs index cbeb71ff8..2d71b8821 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs @@ -24,17 +24,17 @@ namespace VisualPinballUnity { internal static class GateVelocityPhysics { - internal static void UpdateVelocities(ref GateMovementData movementData, in GateStaticData data) + internal static void UpdateVelocities(ref GateMovementState movementState, in GateStaticState state) { - if (!movementData.IsOpen) { - if (math.abs(movementData.Angle) < data.AngleMin + 0.01f && math.abs(movementData.AngleSpeed) < 0.01f) { + if (!movementState.IsOpen) { + if (math.abs(movementState.Angle) < state.AngleMin + 0.01f && math.abs(movementState.AngleSpeed) < 0.01f) { // stop a bit earlier to prevent a nearly endless animation (especially for slow balls) - movementData.Angle = data.AngleMin; - movementData.AngleSpeed = 0.0f; + movementState.Angle = state.AngleMin; + movementState.AngleSpeed = 0.0f; } - if (math.abs(movementData.AngleSpeed) != 0.0f && movementData.Angle != data.AngleMin) { - movementData.AngleSpeed -= math.sin(movementData.Angle) * data.GravityFactor * (float)(PhysicsConstants.PhysFactor / 100.0); // Center of gravity towards bottom of object, makes it stop vertical - movementData.AngleSpeed *= data.Damping; + if (math.abs(movementState.AngleSpeed) != 0.0f && movementState.Angle != state.AngleMin) { + movementState.AngleSpeed -= math.sin(movementState.Angle) * state.GravityFactor * (float)(PhysicsConstants.PhysFactor / 100.0); // Center of gravity towards bottom of object, makes it stop vertical + movementState.AngleSpeed *= state.Damping; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs index df95bfdec..9beebb371 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs @@ -21,51 +21,51 @@ namespace VisualPinballUnity { internal static class DropTargetAnimation { - internal static void Update(int itemId, ref DropTargetAnimationData data, in DropTargetStaticData staticData, + internal static void Update(int itemId, ref DropTargetAnimationState animation, in DropTargetStaticState staticState, ref PhysicsState state) { - var oldTimeMsec = data.TimeMsec < state.Env.TimeMsec ? data.TimeMsec : state.Env.TimeMsec; - data.TimeMsec = state.Env.TimeMsec; + var oldTimeMsec = animation.TimeMsec < state.Env.TimeMsec ? animation.TimeMsec : state.Env.TimeMsec; + animation.TimeMsec = state.Env.TimeMsec; var diffTimeMsec = (float)(state.Env.TimeMsec - oldTimeMsec); - if (data.HitEvent) { - if (!data.IsDropped) { - data.MoveDown = true; + if (animation.HitEvent) { + if (!animation.IsDropped) { + animation.MoveDown = true; } - data.MoveAnimation = true; - data.HitEvent = false; + animation.MoveAnimation = true; + animation.HitEvent = false; } - if (data.MoveAnimation) { - var step = staticData.Speed; + if (animation.MoveAnimation) { + var step = staticState.Speed; - if (data.MoveDown) { + if (animation.MoveDown) { step = -step; - } else if (data.TimeMsec - data.TimeStamp < (uint) staticData.RaiseDelay) { + } else if (animation.TimeMsec - animation.TimeStamp < (uint) staticState.RaiseDelay) { step = 0.0f; } - data.ZOffset += step * diffTimeMsec; - if (data.MoveDown) { - if (data.ZOffset <= -DropTargetAnimationData.DropTargetLimit) { - data.ZOffset = -DropTargetAnimationData.DropTargetLimit; - data.MoveDown = false; - data.IsDropped = true; - data.MoveAnimation = false; - data.TimeStamp = 0; - if (staticData.UseHitEvent) { + animation.ZOffset += step * diffTimeMsec; + if (animation.MoveDown) { + if (animation.ZOffset <= -DropTargetAnimationState.DropTargetLimit) { + animation.ZOffset = -DropTargetAnimationState.DropTargetLimit; + animation.MoveDown = false; + animation.IsDropped = true; + animation.MoveAnimation = false; + animation.TimeStamp = 0; + if (staticState.UseHitEvent) { state.EventQueue.Enqueue(new EventData(EventId.TargetEventsDropped, itemId)); } } } else { - if (data.ZOffset >= 0.0f) { - data.ZOffset = 0.0f; - data.MoveAnimation = false; - data.IsDropped = false; - if (staticData.UseHitEvent) { + if (animation.ZOffset >= 0.0f) { + animation.ZOffset = 0.0f; + animation.MoveAnimation = false; + animation.IsDropped = false; + if (staticState.UseHitEvent) { state.EventQueue.Enqueue(new EventData(EventId.TargetEventsRaised, itemId)); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationState.cs similarity index 92% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationState.cs index c2dd115fb..2cc6d2c50 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct DropTargetAnimationData + internal struct DropTargetAnimationState { public const float DropTargetLimit = 52.0f; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimationState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs index 23b847ae7..65bc6a1c6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs @@ -38,7 +38,7 @@ public override bool IsLegacy { protected override float ZOffset { get { var animationComponent = GetComponentInChildren(); - return animationComponent && animationComponent.IsDropped ? -DropTargetAnimationData.DropTargetLimit : 0f; + return animationComponent && animationComponent.IsDropped ? -DropTargetAnimationState.DropTargetLimit : 0f; } } @@ -149,17 +149,17 @@ internal DropTargetState CreateState() var animationComponent = GetComponentInChildren(); var staticData = colliderComponent && animationComponent - ? new DropTargetStaticData { + ? new DropTargetStaticState { Speed = animationComponent.Speed, RaiseDelay = animationComponent.RaiseDelay, UseHitEvent = colliderComponent.UseHitEvent, } : default; var animationData = colliderComponent && animationComponent - ? new DropTargetAnimationData { + ? new DropTargetAnimationState { IsDropped = animationComponent.IsDropped, MoveDown = !animationComponent.IsDropped, - ZOffset = animationComponent.IsDropped ? -DropTargetAnimationData.DropTargetLimit : 0f + ZOffset = animationComponent.IsDropped ? -DropTargetAnimationState.DropTargetLimit : 0f } : default; return new DropTargetState( diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs index d4492dcde..b5434468e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetState.cs @@ -20,10 +20,10 @@ internal struct DropTargetState { internal readonly int ItemId; internal readonly int AnimatedItemId; - internal DropTargetStaticData Static; - internal DropTargetAnimationData Animation; + internal DropTargetStaticState Static; + internal DropTargetAnimationState Animation; - public DropTargetState(int itemId, int animatedItemId, DropTargetStaticData @static, DropTargetAnimationData animation) + public DropTargetState(int itemId, int animatedItemId, DropTargetStaticState @static, DropTargetAnimationState animation) { ItemId = itemId; AnimatedItemId = animatedItemId; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticState.cs similarity index 92% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticState.cs index dec0f2b8d..dceafc631 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct DropTargetStaticData + internal struct DropTargetStaticState { public float Speed; public float RaiseDelay; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetStaticState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs index 0e9c2b177..a26479ee3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs @@ -22,18 +22,18 @@ namespace VisualPinball.Unity internal static class TargetCollider { public static void DropTargetCollide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, - ref DropTargetAnimationData animationData, in float3 normal, in CollisionEventData collEvent, + ref DropTargetAnimationState animation, in float3 normal, in CollisionEventData collEvent, in Collider coll, ref Random random) { - if (animationData.IsDropped) { + if (animation.IsDropped) { return; } var dot = -math.dot(collEvent.HitNormal, ball.Velocity); BallCollider.Collide3DWall(ref ball, in coll.Header.Material, in collEvent, in normal, ref random); - if (coll.FireEvents && dot >= coll.Threshold && !animationData.IsDropped) { - animationData.HitEvent = true; + if (coll.FireEvents && dot >= coll.Threshold && !animation.IsDropped) { + animation.HitEvent = true; //todo m_obj->m_currentHitThreshold = dot; Collider.FireHitEvent(ref ball, ref hitEvents, in coll.Header); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs index a337d0e2d..288edd319 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs @@ -33,16 +33,16 @@ internal static class KickerCollider public const bool ForceLegacyMode = false; public static void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, - ref InsideOfs insideOfs, ref KickerCollisionData collData, in KickerStaticData staticData, + ref InsideOfs insideOfs, ref KickerCollisionState collState, in KickerStaticState staticState, in ColliderMeshData meshData, in CollisionEventData collEvent, in int itemId) { // a previous ball already in kicker? - if (collData.HasBall) { + if (collState.HasBall) { return; } // ReSharper disable once ConditionIsAlwaysTrueOrFalse - var legacyMode = ForceLegacyMode || staticData.LegacyMode; + var legacyMode = ForceLegacyMode || staticState.LegacyMode; var hitNormal = collEvent.HitNormal; var hitBit = collEvent.HitFlag; @@ -58,7 +58,7 @@ public static void Collide(ref BallState ball, ref NativeQueue.Parall // entering Kickers volume if (!isBallInside) { - var grabHeight = (staticData.ZLow + ball.Radius) * staticData.HitAccuracy; + var grabHeight = (staticState.ZLow + ball.Radius) * staticState.HitAccuracy; // early out here if the ball is slow and we are near the kicker center var hitEvent = ball.Position.z < grabHeight || legacyMode; @@ -81,17 +81,17 @@ public static void Collide(ref BallState ball, ref NativeQueue.Parall } else { - ball.IsFrozen = !staticData.FallThrough; + ball.IsFrozen = !staticState.FallThrough; if (ball.IsFrozen) { insideOfs.SetInsideOf(itemId, ball.Id); // add kicker to ball's volume set - collData.BallId = ball.Id; - collData.LastCapturedBallId = ball.Id; + collState.BallId = ball.Id; + collState.LastCapturedBallId = ball.Id; } // Fire the event before changing ball attributes, so scripters can get a useful ball state events.Enqueue(new EventData(EventId.HitEventsHit, itemId, ball.Id, true)); - if (ball.IsFrozen || staticData.FallThrough) { // script may have unfrozen the ball + if (ball.IsFrozen || staticState.FallThrough) { // script may have unfrozen the ball // if ball falls through hole, we fake the collision algo by changing the ball height // in HitTestBasicRadius() the z-position of the ball is checked if it is >= to the hit cylinder @@ -100,15 +100,15 @@ public static void Collide(ref BallState ball, ref NativeQueue.Parall // Only mess with variables if ball was not kicked during event ball.Velocity = float3.zero; ball.AngularMomentum = float3.zero; - var posZ = !staticData.FallIn - ? staticData.ZLow + ball.Radius * 2 - : staticData.FallThrough - ? staticData.ZLow - ball.Radius - 5.0f - : staticData.ZLow + ball.Radius; - ball.Position = new float3(staticData.Center.x, staticData.Center.y, posZ); + var posZ = !staticState.FallIn + ? staticState.ZLow + ball.Radius * 2 + : staticState.FallThrough + ? staticState.ZLow - ball.Radius - 5.0f + : staticState.ZLow + ball.Radius; + ball.Position = new float3(staticState.Center.x, staticState.Center.y, posZ); } else { - collData.BallId = 0; // make sure + collState.BallId = 0; // make sure } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionState.cs similarity index 91% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionState.cs index 667f51c8f..2f0980a8d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionState.cs @@ -18,7 +18,7 @@ namespace VisualPinball.Unity { - internal struct KickerCollisionData : IComponentData + internal struct KickerCollisionState : IComponentData { public int BallId; public int LastCapturedBallId; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs index dacebf764..c4d60df49 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs @@ -264,7 +264,7 @@ internal KickerState CreateState() // collision var colliderComponent = GetComponent(); var staticData = colliderComponent - ? new KickerStaticData { + ? new KickerStaticState { Center = Position, FallIn = colliderComponent.FallIn, FallThrough = colliderComponent.FallThrough, @@ -282,7 +282,7 @@ internal KickerState CreateState() return new KickerState( colliderComponent ? colliderComponent.gameObject.GetInstanceID() : 0, staticData, - new KickerCollisionData(), + new KickerCollisionState(), meshData ); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs index 9e495eba4..21c3133d2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs @@ -19,11 +19,11 @@ namespace VisualPinball.Unity internal struct KickerState { internal readonly int ItemId; - internal KickerStaticData Static; - internal KickerCollisionData Collision; + internal KickerStaticState Static; + internal KickerCollisionState Collision; internal ColliderMeshData CollisionMesh; - public KickerState(int itemId, KickerStaticData @static, KickerCollisionData collision, ColliderMeshData collisionMesh) + public KickerState(int itemId, KickerStaticState @static, KickerCollisionState collision, ColliderMeshData collisionMesh) { ItemId = itemId; Static = @static; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticState.cs similarity index 92% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticState.cs index 95fc7aaa8..9a95ae63f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticState.cs @@ -19,7 +19,7 @@ namespace VisualPinball.Unity { - internal struct KickerStaticData : IComponentData + internal struct KickerStaticState : IComponentData { public bool LegacyMode; public bool FallThrough; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs index 995d66234..1ff277717 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs @@ -21,13 +21,13 @@ namespace VisualPinballUnity { internal static class PlungerAnimation { - internal static void Update(ref PlungerAnimationData animationData, in PlungerMovementData movementData, - in PlungerStaticData staticData) + internal static void Update(ref PlungerAnimationState animation, in PlungerMovementState movement, + in PlungerStaticState staticState) { - var frame0 = (int)((movementData.Position - staticData.FrameStart) / (staticData.FrameEnd - staticData.FrameStart) * (staticData.NumFrames - 1) + 0.5f); - var frame = frame0 < 0 ? 0 : frame0 >= staticData.NumFrames ? staticData.NumFrames - 1 : frame0; + var frame0 = (int)((movement.Position - staticState.FrameStart) / (staticState.FrameEnd - staticState.FrameStart) * (staticState.NumFrames - 1) + 0.5f); + var frame = frame0 < 0 ? 0 : frame0 >= staticState.NumFrames ? staticState.NumFrames - 1 : frame0; - animationData.Position = math.clamp((float)frame / staticData.NumFrames, 0, 1); + animation.Position = math.clamp((float)frame / staticState.NumFrames, 0, 1); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationState.cs similarity index 92% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationState.cs index d37b9a74a..bdf88f16e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct PlungerAnimationData + internal struct PlungerAnimationState { public float Position; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimationState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs index b03ad65b5..3e323f382 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs @@ -78,7 +78,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray 0.05f ? ball.Mass : 0.05f; - var xferRatio = staticData.MomentumXfer / ballMass; - var deltaY = movementData.Speed * xferRatio; + var xferRatio = staticState.MomentumXfer / ballMass; + var deltaY = movement.Speed * xferRatio; // check the moving bits - newTime = LineCollider.HitTest(ref newCollEvent, ref insideOfs, in colliderData.LineSegEnd, in ballTmp, hitTime); + newTime = LineCollider.HitTest(ref newCollEvent, ref insideOfs, in colliderState.LineSegEnd, in ballTmp, hitTime); UpdateCollision(ref collEvent, ref newCollEvent, ref isHit, ref hitTime, in newTime, deltaY); - newTime = LineZCollider.HitTest(ref newCollEvent, in colliderData.JointEnd0, in ballTmp, hitTime); + newTime = LineZCollider.HitTest(ref newCollEvent, in colliderState.JointEnd0, in ballTmp, hitTime); UpdateCollision(ref collEvent, ref newCollEvent, ref isHit, ref hitTime, in newTime, deltaY); - newTime = LineZCollider.HitTest(ref newCollEvent, in colliderData.JointEnd1, in ballTmp, hitTime); + newTime = LineZCollider.HitTest(ref newCollEvent, in colliderState.JointEnd1, in ballTmp, hitTime); UpdateCollision(ref collEvent, ref newCollEvent, ref isHit, ref hitTime, in newTime, deltaY); // check only if the plunger is not in a controlled retract motion // and check for a hit - if (isHit && !movementData.RetractMotion) { + if (isHit && !movement.RetractMotion) { // We hit the ball. Set a travel limit to freeze the plunger at // its current position for the next displacement update. This // is necessary in case we have a relatively heavy ball with a @@ -192,8 +192,8 @@ public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, // enough to let the ball move a little bit, so that there's a // non-zero time to the next collision with the plunger. We'll // then catch up again and push it along a little further. - if (movementData.TravelLimit < movementData.Position) { - movementData.TravelLimit = movementData.Position; + if (movement.TravelLimit < movement.Position) { + movement.TravelLimit = movement.Position; } // If the distance is negative, it means the objects are @@ -230,7 +230,7 @@ private static void UpdateCollision(ref CollisionEventData collEvent, #region Collision public static void Collide(ref BallState ball, ref CollisionEventData collEvent, - ref PlungerMovementData movementData, in PlungerStaticData staticData, ref Random random) + ref PlungerMovementState movement, in PlungerStaticState staticState, ref Random random) { var dot = (ball.Velocity.x - collEvent.HitVelocity.x) * collEvent.HitNormal.x + (ball.Velocity.y - collEvent.HitVelocity.y) * collEvent.HitNormal.y; @@ -277,7 +277,7 @@ public static void Collide(ref BallState ball, ref CollisionEventData collEvent, // for a Fire event. Real plungers bounce quite a bit when fired without // hitting anything, but bounce much less when they hit something, since // most of the momentum gets transferred out of the plunger and to the ball. - movementData.FireBounce *= 0.6f; + movement.FireBounce *= 0.6f; // Check for a downward collision with the tip. This is the moving // part of the plunger, so it has some special handling. @@ -299,7 +299,7 @@ public static void Collide(ref BallState ball, ref CollisionEventData collEvent, // isn't entirely unreasonable physically - you could look at it as // accounting for the spring tension and friction. const float reverseImpulseFudgeFactor = .22f; - movementData.ReverseImpulse = ball.Velocity.y * impulse + movement.ReverseImpulse = ball.Velocity.y * impulse * (ball.Mass / Plunger.PlungerMass) * reverseImpulseFudgeFactor; } @@ -309,7 +309,7 @@ public static void Collide(ref BallState ball, ref CollisionEventData collEvent, ball.Velocity *= 0.999f; //friction all axiz //!! TODO: fix this var scatterVel = - staticData.ScatterVelocity * + staticState.ScatterVelocity * 0.2f; // todo g_pplayer->m_ptable->m_globalDifficulty;// apply dificulty weighting // skip if low velocity diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderState.cs similarity index 93% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderState.cs index 77de61d0e..526a899e3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct PlungerColliderData + internal struct PlungerColliderState { public LineCollider LineSegSide0; public LineCollider LineSegSide1; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCommands.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCommands.cs index 54a28cd5d..8cf8a1b17 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCommands.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCommands.cs @@ -19,47 +19,47 @@ namespace VisualPinball.Unity internal static class PlungerCommands { - public static void PullBack(float speed, ref PlungerVelocityData velocityData, ref PlungerMovementData movementData) + public static void PullBack(float speed, ref PlungerVelocityState velocity, ref PlungerMovementState movement) { - movementData.Speed = 0.0f; - velocityData.PullForce = speed; + movement.Speed = 0.0f; + velocity.PullForce = speed; // deactivate the retract code - velocityData.AddRetractMotion = false; + velocity.AddRetractMotion = false; } - public static void PullBackAndRetract(float speedPull, ref PlungerVelocityData velocityData, ref PlungerMovementData movementData) + public static void PullBackAndRetract(float speedPull, ref PlungerVelocityState velocity, ref PlungerMovementState movement) { - movementData.Speed = 0.0f; - velocityData.PullForce = speedPull; + movement.Speed = 0.0f; + velocity.PullForce = speedPull; // deactivate the retract code - velocityData.AddRetractMotion = false; - movementData.RetractMotion = false; - velocityData.InitialSpeed = speedPull; + velocity.AddRetractMotion = false; + movement.RetractMotion = false; + velocity.InitialSpeed = speedPull; } - public static void Fire(float startPos, ref PlungerVelocityData velocityData, ref PlungerMovementData movementData, in PlungerStaticData staticData) + public static void Fire(float startPos, ref PlungerVelocityState velocity, ref PlungerMovementState movement, in PlungerStaticState staticState) { // cancel any pull force - velocityData.PullForce = 0.0f; + velocity.PullForce = 0.0f; // make sure the starting point is behind the park position - if (startPos < staticData.RestPosition) { - startPos = staticData.RestPosition; + if (startPos < staticState.RestPosition) { + startPos = staticState.RestPosition; } // move immediately to the starting position - movementData.Position = staticData.FrameEnd + startPos * staticData.FrameLen; + movement.Position = staticState.FrameEnd + startPos * staticState.FrameLen; // Figure the release speed as a fraction of the // fire speed property, linearly proportional to the // starting distance. Note that the release motion // is upwards, so the speed is negative. - var dx = startPos - staticData.RestPosition; + var dx = startPos - staticState.RestPosition; const float normalize = Engine.VPT.Plunger.Plunger.PlungerNormalize / 13.0f / 100.0f; - movementData.FireSpeed = -staticData.SpeedFire - * dx * staticData.FrameLen / Engine.VPT.Plunger.Plunger.PlungerMass + movement.FireSpeed = -staticState.SpeedFire + * dx * staticState.FrameLen / Engine.VPT.Plunger.Plunger.PlungerMass * normalize; // Figure the target stopping position for the @@ -74,12 +74,12 @@ public static void Fire(float startPos, ref PlungerVelocityData velocityData, re // the initial bounce will be negative, since we're moving upwards, // and we calculated it as a fraction of the forward travel distance // (which is the part between 0 and the rest position) - movementData.FireBounce = -bounceDist * staticData.RestPosition; + movement.FireBounce = -bounceDist * staticState.RestPosition; // enter Fire mode for long enough for the process to complete - movementData.FireTimer = 200; + movement.FireTimer = 200; - movementData.RetractMotion = false; + movement.RetractMotion = false; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs index 783f67ab0..f18149185 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs @@ -299,7 +299,7 @@ internal PlungerState CreateState() return new PlungerState( gameObject.GetInstanceID(), - new PlungerStaticData { + new PlungerStaticState { MomentumXfer = collComponent.MomentumXfer, ScatterVelocity = collComponent.ScatterVelocity, FrameStart = frameBottom, @@ -311,14 +311,14 @@ internal PlungerState CreateState() SpeedFire = collComponent.SpeedFire, NumFrames = (int)(collComponent.Stroke * (float)(PlungerMeshGenerator.PlungerFrameCount / 80.0f)) + 1, // 25 frames per 80 units travel }, - new PlungerColliderData { + new PlungerColliderState { LineSegSide0 = new LineCollider(new float2(x + 0.0001f, position), new float2(x, y), zHeight, zHeight + Plunger.PlungerHeight, info), LineSegSide1 = new LineCollider(new float2(x2, y), new float2(x2 + 0.0001f, position), zHeight, zHeight + Plunger.PlungerHeight, info), LineSegEnd = new LineCollider(new float2(x2, position), new float2(x, position), zHeight, zHeight + Plunger.PlungerHeight, info), JointEnd0 = new LineZCollider(new float2(x, position), zHeight, zHeight + Plunger.PlungerHeight, info), JointEnd1 = new LineZCollider(new float2(x2, position), zHeight, zHeight + Plunger.PlungerHeight, info), }, - new PlungerMovementData { + new PlungerMovementState { FireBounce = 0f, Position = position, RetractMotion = false, @@ -328,7 +328,7 @@ internal PlungerState CreateState() FireSpeed = 0f, FireTimer = 0 }, - new PlungerVelocityData { + new PlungerVelocityState { Mech0 = 0f, Mech1 = 0f, Mech2 = 0f, @@ -339,7 +339,7 @@ internal PlungerState CreateState() RetractWaitLoop = 0, MechStrength = collComponent.MechStrength }, - new PlungerAnimationData { + new PlungerAnimationState { Position = collComponent.ParkPosition } ); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs index 3bb08b5f4..24360d318 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs @@ -23,97 +23,97 @@ namespace VisualPinballUnity { internal static class PlungerDisplacementPhysics { - internal static void UpdateDisplacement(int itemId, ref PlungerMovementData movementData, - ref PlungerColliderData colliderData, in PlungerStaticData staticData, float dTime, + internal static void UpdateDisplacement(int itemId, ref PlungerMovementState movement, + ref PlungerColliderState colliderState, in PlungerStaticState staticState, float dTime, ref NativeQueue.ParallelWriter events) { // figure the travel distance - var dx = dTime * movementData.Speed; + var dx = dTime * movement.Speed; // figure the position change - movementData.Position += dx; + movement.Position += dx; // apply the travel limit - if (movementData.Position < movementData.TravelLimit) { - movementData.Position = movementData.TravelLimit; + if (movement.Position < movement.TravelLimit) { + movement.Position = movement.TravelLimit; } // if we're in firing mode and we've crossed the bounce position, reverse course - var relPos = (movementData.Position - staticData.FrameEnd) / staticData.FrameLen; - var bouncePos = staticData.RestPosition + movementData.FireBounce; - if (movementData.FireTimer != 0 && dTime != 0.0f && - (movementData.FireSpeed < 0.0f ? relPos <= bouncePos : relPos >= bouncePos)) + var relPos = (movement.Position - staticState.FrameEnd) / staticState.FrameLen; + var bouncePos = staticState.RestPosition + movement.FireBounce; + if (movement.FireTimer != 0 && dTime != 0.0f && + (movement.FireSpeed < 0.0f ? relPos <= bouncePos : relPos >= bouncePos)) { // stop at the bounce position - movementData.Position = staticData.FrameEnd + bouncePos * staticData.FrameLen; + movement.Position = staticState.FrameEnd + bouncePos * staticState.FrameLen; // reverse course at reduced speed - movementData.FireSpeed = -movementData.FireSpeed * 0.4f; + movement.FireSpeed = -movement.FireSpeed * 0.4f; // figure the new bounce as a fraction of the previous bounce - movementData.FireBounce *= -0.4f; + movement.FireBounce *= -0.4f; } // apply the travel limit (again) - if (movementData.Position < movementData.TravelLimit) { - movementData.Position = movementData.TravelLimit; + if (movement.Position < movement.TravelLimit) { + movement.Position = movement.TravelLimit; } // limit motion to the valid range if (dTime != 0.0f) { - if (movementData.Position < staticData.FrameEnd) { - movementData.Speed = 0.0f; - movementData.Position = staticData.FrameEnd; + if (movement.Position < staticState.FrameEnd) { + movement.Speed = 0.0f; + movement.Position = staticState.FrameEnd; - } else if (movementData.Position > staticData.FrameStart) { - movementData.Speed = 0.0f; - movementData.Position = staticData.FrameStart; + } else if (movement.Position > staticState.FrameStart) { + movement.Speed = 0.0f; + movement.Position = staticState.FrameStart; } // apply the travel limit (yet again) - if (movementData.Position < movementData.TravelLimit) { - movementData.Position = movementData.TravelLimit; + if (movement.Position < movement.TravelLimit) { + movement.Position = movement.TravelLimit; } } // the travel limit applies to one displacement update only - reset it - movementData.TravelLimit = staticData.FrameEnd; + movement.TravelLimit = staticState.FrameEnd; // fire an Start/End of Stroke events, as appropriate - var strokeEventLimit = staticData.FrameLen / 50.0f; + var strokeEventLimit = staticState.FrameLen / 50.0f; var strokeEventHysteresis = strokeEventLimit * 2.0f; - if (movementData.StrokeEventsArmed && movementData.Position + dx > staticData.FrameStart - strokeEventLimit) { - events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, math.abs(movementData.Speed))); - movementData.StrokeEventsArmed = false; + if (movement.StrokeEventsArmed && movement.Position + dx > staticState.FrameStart - strokeEventLimit) { + events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, math.abs(movement.Speed))); + movement.StrokeEventsArmed = false; - } else if (movementData.StrokeEventsArmed && movementData.Position + dx < staticData.FrameEnd + strokeEventLimit) { - events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, math.abs(movementData.Speed))); - movementData.StrokeEventsArmed = false; + } else if (movement.StrokeEventsArmed && movement.Position + dx < staticState.FrameEnd + strokeEventLimit) { + events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, math.abs(movement.Speed))); + movement.StrokeEventsArmed = false; - } else if (movementData.Position > staticData.FrameEnd + strokeEventHysteresis && movementData.Position < staticData.FrameStart - strokeEventHysteresis) { + } else if (movement.Position > staticState.FrameEnd + strokeEventHysteresis && movement.Position < staticState.FrameStart - strokeEventHysteresis) { // away from the limits - arm the stroke events - movementData.StrokeEventsArmed = true; + movement.StrokeEventsArmed = true; } // update the display - UpdateCollider(movementData.Position, ref colliderData); + UpdateCollider(movement.Position, ref colliderState); } - private static void UpdateCollider(float len, ref PlungerColliderData colliderData) + private static void UpdateCollider(float len, ref PlungerColliderState colliderState) { - colliderData.LineSegSide0.V1y = len; - colliderData.LineSegSide1.V2y = len; + colliderState.LineSegSide0.V1y = len; + colliderState.LineSegSide1.V2y = len; - colliderData.LineSegEnd.V2y = len; - colliderData.LineSegEnd.V1y = len; // + 0.0001f; + colliderState.LineSegEnd.V2y = len; + colliderState.LineSegEnd.V1y = len; // + 0.0001f; - colliderData.JointEnd0.XyY = len; - colliderData.JointEnd1.XyY = len; // + 0.0001f; + colliderState.JointEnd0.XyY = len; + colliderState.JointEnd1.XyY = len; // + 0.0001f; - colliderData.LineSegSide0.CalcNormal(); - colliderData.LineSegSide1.CalcNormal(); - colliderData.LineSegEnd.CalcNormal(); + colliderState.LineSegSide0.CalcNormal(); + colliderState.LineSegSide1.CalcNormal(); + colliderState.LineSegEnd.CalcNormal(); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementState.cs similarity index 97% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementState.cs index 419db76ca..6e3684dc4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct PlungerMovementData + internal struct PlungerMovementState { /// /// Current rod speed, in table distance units per second(?) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerMovementState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs index e0d3f91e6..66acf2347 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerState.cs @@ -19,13 +19,13 @@ namespace VisualPinball.Unity internal struct PlungerState { internal readonly int ItemId; - internal PlungerStaticData Static; - internal PlungerColliderData Collider; - internal PlungerMovementData Movement; - internal PlungerVelocityData Velocity; - internal PlungerAnimationData Animation; + internal PlungerStaticState Static; + internal PlungerColliderState Collider; + internal PlungerMovementState Movement; + internal PlungerVelocityState Velocity; + internal PlungerAnimationState Animation; - public PlungerState(int itemId, PlungerStaticData @static, PlungerColliderData collider, PlungerMovementData movement, PlungerVelocityData velocity, PlungerAnimationData animation) + public PlungerState(int itemId, PlungerStaticState @static, PlungerColliderState collider, PlungerMovementState movement, PlungerVelocityState velocity, PlungerAnimationState animation) { ItemId = itemId; Static = @static; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticState.cs similarity index 93% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticState.cs index c18030e69..487268844 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct PlungerStaticData + internal struct PlungerStaticState { // collision public float MomentumXfer; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerStaticState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs index fd4e7c2ba..08a2ced25 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs @@ -21,18 +21,18 @@ namespace VisualPinballUnity { internal static class PlungerVelocityPhysics { - internal static void UpdateVelocities(ref PlungerMovementData movementData, ref PlungerVelocityData velocityData, - in PlungerStaticData staticData) + internal static void UpdateVelocities(ref PlungerMovementState movement, ref PlungerVelocityState velocity, + in PlungerStaticState staticState) { // figure our current position in relative coordinates (0.0-1.0, // where 0.0 is the maximum forward position and 1.0 is the // maximum retracted position) - var pos = (movementData.Position - staticData.FrameEnd) / staticData.FrameLen; + var pos = (movement.Position - staticState.FrameEnd) / staticState.FrameLen; - var mech = staticData.IsMechPlunger ? movementData.AnalogPosition : 0.0f; + var mech = staticState.IsMechPlunger ? movement.AnalogPosition : 0.0f; // calculate the delta from the last reading - var dMech = velocityData.Mech0 - mech; + var dMech = velocity.Mech0 - mech; // Frame-to-frame mech movement threshold for detecting a release // motion. 1.0 is the full range of travel, which corresponds @@ -54,10 +54,10 @@ internal static void UpdateVelocities(ref PlungerMovementData movementData, ref const float releaseThreshold = 0.2f; // note if we're acting as an auto plunger - var autoPlunger = staticData.IsAutoPlunger; + var autoPlunger = staticState.IsAutoPlunger; // check which forces are acting on us - if (movementData.FireTimer > 0) { + if (movement.FireTimer > 0) { // Fire mode. In this mode, we're moving freely under the spring // forces at the speed we calculated when we initiated the release. // Simply leave the speed unchanged. @@ -68,17 +68,17 @@ internal static void UpdateVelocities(ref PlungerMovementData movementData, ref // mode, and also allows us to sync up again with the real // plunger after a respectable pause if the user is just // moving it around a lot. - movementData.Speed = movementData.FireSpeed; - --movementData.FireTimer; + movement.Speed = movement.FireSpeed; + --movement.FireTimer; - } else if (velocityData.AutoFireTimer > 0) { + } else if (velocity.AutoFireTimer > 0) { // The Auto Fire timer is running. We start this timer when we // send a synthetic KeyDown(Return) event to the script to simulate // a Launch Ball event when the user pulls back and releases the // mechanical plunger and we're operating as an auto plunger. // When the timer reaches zero, we'll send the corresponding // KeyUp event and cancel the timer. - if (--velocityData.AutoFireTimer == 0) { + if (--velocity.AutoFireTimer == 0) { // todo event // if (g_pplayer != 0) { // g_pplayer->m_ptable->FireKeyEvent(DISPID_GameEvents_KeyUp, g_pplayer->m_rgKeys[ePlungerKey]); @@ -126,9 +126,9 @@ internal static void UpdateVelocities(ref PlungerMovementData movementData, ref // } // start the timer to send the corresponding KeyUp in 100ms - velocityData.AutoFireTimer = 101; + velocity.AutoFireTimer = 101; - } else if (velocityData.PullForce != 0.0f) { + } else if (velocity.PullForce != 0.0f) { // A "pull" force is in effect. This is a *simulated* pull, so // it overrides the real physical plunger position. // @@ -140,21 +140,21 @@ internal static void UpdateVelocities(ref PlungerMovementData movementData, ref // but we can elide the elapsed time factor because it's // effectively a constant that's implicitly folded into the // pull force value. - movementData.Speed += velocityData.PullForce / Plunger.PlungerMass; + movement.Speed += velocity.PullForce / Plunger.PlungerMass; - if (!velocityData.AddRetractMotion) { + if (!velocity.AddRetractMotion) { // this is the normal PullBack branch // if we're already at the maximum retracted position, stop - if (movementData.Position > staticData.FrameStart) { - movementData.Speed = 0.0f; - movementData.Position = staticData.FrameStart; + if (movement.Position > staticState.FrameStart) { + movement.Speed = 0.0f; + movement.Position = staticState.FrameStart; } // if we're already at the minimum retracted position, stop - if (movementData.Position < staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen) { - movementData.Speed = 0.0f; - movementData.Position = staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen; + if (movement.Position < staticState.FrameEnd + staticState.RestPosition * staticState.FrameLen) { + movement.Speed = 0.0f; + movement.Position = staticState.FrameEnd + staticState.RestPosition * staticState.FrameLen; } } else { @@ -162,30 +162,30 @@ internal static void UpdateVelocities(ref PlungerMovementData movementData, ref // after reaching the max. position the plunger should retract until it reaches the min. position and then start again // if we're already at the maximum retracted position, reverse - if (movementData.Position >= staticData.FrameStart && velocityData.PullForce > 0) { - movementData.Speed = 0.0f; - movementData.Position = staticData.FrameStart; - velocityData.RetractWaitLoop++; - if (velocityData.RetractWaitLoop > 1000) { // 1 sec, related to PHYSICS_STEPTIME - velocityData.PullForce = -velocityData.InitialSpeed; - movementData.Position = staticData.FrameStart; - movementData.RetractMotion = true; - velocityData.RetractWaitLoop = 0; + if (movement.Position >= staticState.FrameStart && velocity.PullForce > 0) { + movement.Speed = 0.0f; + movement.Position = staticState.FrameStart; + velocity.RetractWaitLoop++; + if (velocity.RetractWaitLoop > 1000) { // 1 sec, related to PHYSICS_STEPTIME + velocity.PullForce = -velocity.InitialSpeed; + movement.Position = staticState.FrameStart; + movement.RetractMotion = true; + velocity.RetractWaitLoop = 0; } } // if we're already at the minimum retracted position, start again - if (movementData.Position <= staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen && velocityData.PullForce <= 0) { - movementData.Speed = 0.0f; - velocityData.PullForce = velocityData.InitialSpeed; - movementData.Position = staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen; + if (movement.Position <= staticState.FrameEnd + staticState.RestPosition * staticState.FrameLen && velocity.PullForce <= 0) { + movement.Speed = 0.0f; + velocity.PullForce = velocity.InitialSpeed; + movement.Position = staticState.FrameEnd + staticState.RestPosition * staticState.FrameLen; } // reset retract motion indicator only after the rest position has been left, to avoid ball interactions // use a linear pullback motion - if (movementData.Position > 1.0f + staticData.FrameEnd + staticData.RestPosition * staticData.FrameLen && velocityData.PullForce > 0) { - movementData.RetractMotion = false; - movementData.Speed = 3.0f * velocityData.PullForce; // 3 = magic + if (movement.Position > 1.0f + staticState.FrameEnd + staticState.RestPosition * staticState.FrameLen && velocity.PullForce > 0) { + movement.RetractMotion = false; + movement.Speed = 3.0f * velocity.PullForce; // 3 = magic } } @@ -242,16 +242,16 @@ internal static void UpdateVelocities(ref PlungerMovementData movementData, ref // started. Scan the history for monotonically ascending values, // and take the highest one we find. That's probably where the // user actually released the plunger. - var apex = velocityData.Mech0; - if (velocityData.Mech1 > apex) { - apex = velocityData.Mech1; - if (velocityData.Mech2 > apex) { - apex = velocityData.Mech2; + var apex = velocity.Mech0; + if (velocity.Mech1 > apex) { + apex = velocity.Mech1; + if (velocity.Mech2 > apex) { + apex = velocity.Mech2; } } // trigger a release from the apex position - PlungerCommands.Fire(apex, ref velocityData, ref movementData, in staticData); + PlungerCommands.Fire(apex, ref velocity, ref movement, in staticState); } else { // Normal mode, and NOT firing the plunger. In this mode, we @@ -272,7 +272,7 @@ internal static void UpdateVelocities(ref PlungerMovementData movementData, ref // for a normal plunger, sync to the mech plunger; otherwise // just go to the rest position - var target = autoPlunger ? staticData.RestPosition : mech; + var target = autoPlunger ? staticState.RestPosition : mech; // figure the current difference in positions var error = target - pos; @@ -305,24 +305,24 @@ internal static void UpdateVelocities(ref PlungerMovementData movementData, ref const float plungerFriction = 0.95f; const float normalize = Plunger.PlungerNormalize / 13.0f / 100.0f; const float dt = 0.1f; - movementData.Speed *= plungerFriction; - movementData.Speed += error * staticData.FrameLen * velocityData.MechStrength / Plunger.PlungerMass * normalize * dt; + movement.Speed *= plungerFriction; + movement.Speed += error * staticState.FrameLen * velocity.MechStrength / Plunger.PlungerMass * normalize * dt; // add any reverse impulse to the result - movementData.Speed += movementData.ReverseImpulse; + movement.Speed += movement.ReverseImpulse; } // cancel any reverse impulse - movementData.ReverseImpulse = 0.0f; + movement.ReverseImpulse = 0.0f; // Shift the current mech reading into the history list, if it's // different from the last reading. Only keep distinct readings; // the physics loop tends to run faster than the USB reporting // rate, so we might see the same USB report several times here. - if (mech != velocityData.Mech0) { - velocityData.Mech2 = velocityData.Mech1; - velocityData.Mech1 = velocityData.Mech0; - velocityData.Mech0 = mech; + if (mech != velocity.Mech0) { + velocity.Mech2 = velocity.Mech1; + velocity.Mech1 = velocity.Mech0; + velocity.Mech0 = mech; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityState.cs similarity index 96% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityState.cs index f429bbb60..5224dc0c9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct PlungerVelocityData + internal struct PlungerVelocityState { /// /// Recent history of mechanical plunger readings. We keep the diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs index cca79eec7..5f3c17054 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs @@ -101,7 +101,7 @@ public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, #region Collision - public static void Collide(in BallState ball, ref CollisionEventData collEvent, ref SpinnerMovementData movementData, in SpinnerStaticData data) + public static void Collide(in BallState ball, ref CollisionEventData collEvent, ref SpinnerMovementState movement, in SpinnerStaticState state) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); @@ -110,7 +110,7 @@ public static void Collide(in BallState ball, ref CollisionEventData collEvent, return; } - var h = data.Height * 0.5f; + var h = state.Height * 0.5f; // linear speed = ball speed // angular speed = linear/radius (height of hit) @@ -119,18 +119,18 @@ public static void Collide(in BallState ball, ref CollisionEventData collEvent, // h -coll.m_radius will be moving a at linear rate of // 'speed'. We can calculate the angular speed from that. - movementData.AngleSpeed = math.abs(dot); // use this until a better value comes along + movement.AngleSpeed = math.abs(dot); // use this until a better value comes along if (math.abs(h) > 1.0f) { // avoid divide by zero - movementData.AngleSpeed /= h; + movement.AngleSpeed /= h; } - movementData.AngleSpeed *= data.Damping; + movement.AngleSpeed *= state.Damping; // We encoded which side of the spinner the ball hit if (collEvent.HitFlag) { - movementData.AngleSpeed = -movementData.AngleSpeed; + movement.AngleSpeed = -movement.AngleSpeed; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs index 7119555a7..af8c092f1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs @@ -251,7 +251,7 @@ internal SpinnerState CreateState() // physics collision data var collComponent = GetComponent(); var staticData = collComponent - ? new SpinnerStaticData { + ? new SpinnerStaticState { AngleMax = math.radians(AngleMax), AngleMin = math.radians(AngleMin), Damping = math.pow(Damping, (float)PhysicsConstants.PhysFactor), @@ -262,7 +262,7 @@ internal SpinnerState CreateState() // animation var animComponent = GetComponentInChildren(); var movementData = animComponent - ? new SpinnerMovementData { + ? new SpinnerMovementState { Angle = math.radians(math.clamp(0.0f, AngleMin, AngleMax)), AngleSpeed = 0f } : default; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs index f3ef752e0..77c36ca1b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs @@ -25,67 +25,67 @@ namespace VisualPinballUnity { internal static class SpinnerDisplacementPhysics { - internal static void UpdateDisplacement(int itemId, ref SpinnerMovementData movementData, in SpinnerStaticData data, + internal static void UpdateDisplacement(int itemId, ref SpinnerMovementState movement, in SpinnerStaticState state, float dTime, ref NativeQueue.ParallelWriter events) { // those are already converted to radian during authoring. - var angleMin = data.AngleMin; - var angleMax = data.AngleMax; + var angleMin = state.AngleMin; + var angleMax = state.AngleMax; // blocked spinner, limited motion spinner - if (data.AngleMin != data.AngleMax) { + if (state.AngleMin != state.AngleMax) { - movementData.Angle += movementData.AngleSpeed * dTime; + movement.Angle += movement.AngleSpeed * dTime; - if (movementData.Angle > angleMax) { - movementData.Angle = angleMax; + if (movement.Angle > angleMax) { + movement.Angle = angleMax; // send EOS event - events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, math.abs(math.degrees(movementData.AngleSpeed)))); + events.Enqueue(new EventData(EventId.LimitEventsEos, itemId, math.abs(math.degrees(movement.AngleSpeed)))); - if (movementData.AngleSpeed > 0.0f) { - movementData.AngleSpeed *= -0.005f - data.Elasticity; + if (movement.AngleSpeed > 0.0f) { + movement.AngleSpeed *= -0.005f - state.Elasticity; } } - if (movementData.Angle < angleMin) { - movementData.Angle = angleMin; + if (movement.Angle < angleMin) { + movement.Angle = angleMin; // send Park event - events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, math.abs(math.degrees(movementData.AngleSpeed)))); + events.Enqueue(new EventData(EventId.LimitEventsBos, itemId, math.abs(math.degrees(movement.AngleSpeed)))); - if (movementData.AngleSpeed < 0.0f) { - movementData.AngleSpeed *= -0.005f - data.Elasticity; + if (movement.AngleSpeed < 0.0f) { + movement.AngleSpeed *= -0.005f - state.Elasticity; } } } else { - var target = movementData.AngleSpeed > 0.0f - ? movementData.Angle < math.PI ? math.PI : 3.0f * math.PI - : movementData.Angle < math.PI ? -math.PI : math.PI; + var target = movement.AngleSpeed > 0.0f + ? movement.Angle < math.PI ? math.PI : 3.0f * math.PI + : movement.Angle < math.PI ? -math.PI : math.PI; - movementData.Angle += movementData.AngleSpeed * dTime; + movement.Angle += movement.AngleSpeed * dTime; - if (movementData.AngleSpeed > 0.0f) { + if (movement.AngleSpeed > 0.0f) { - if (movementData.Angle > target) { + if (movement.Angle > target) { events.Enqueue(new EventData(EventId.SpinnerEventsSpin, itemId, true)); } } else { - if (movementData.Angle < target) { + if (movement.Angle < target) { events.Enqueue(new EventData(EventId.SpinnerEventsSpin, itemId, true)); } } - while (movementData.Angle > 2.0f * math.PI) { - movementData.Angle -= 2.0f * math.PI; + while (movement.Angle > 2.0f * math.PI) { + movement.Angle -= 2.0f * math.PI; } - while (movementData.Angle < 0.0f) { - movementData.Angle += 2.0f * math.PI; + while (movement.Angle < 0.0f) { + movement.Angle += 2.0f * math.PI; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementState.cs similarity index 92% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementState.cs index 1e55b46e6..f759333ff 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct SpinnerMovementData + internal struct SpinnerMovementState { public float Angle; public float AngleSpeed; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerMovementState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs index 21a642161..4fed8ca9d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerState.cs @@ -20,10 +20,10 @@ internal struct SpinnerState { internal readonly int ItemId; internal readonly int AnimationItemId; - internal SpinnerStaticData Static; - internal SpinnerMovementData Movement; + internal SpinnerStaticState Static; + internal SpinnerMovementState Movement; - public SpinnerState(int itemId, int animationItemId, SpinnerStaticData @static, SpinnerMovementData movement) + public SpinnerState(int itemId, int animationItemId, SpinnerStaticState @static, SpinnerMovementState movement) { ItemId = itemId; AnimationItemId = animationItemId; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticState.cs similarity index 93% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticState.cs index 595b5c404..c44a0e0c3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct SpinnerStaticData + internal struct SpinnerStaticState { public float AngleMin; public float AngleMax; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerStaticState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs index a5ec3c684..e6911492f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs @@ -22,11 +22,11 @@ namespace VisualPinballUnity { internal static class SpinnerVelocityPhysics { - internal static void UpdateVelocities(ref SpinnerMovementData movementData, in SpinnerStaticData data) + internal static void UpdateVelocities(ref SpinnerMovementState movement, in SpinnerStaticState state) { // Center of gravity towards bottom of object, makes it stop vertical - movementData.AngleSpeed -= math.sin(movementData.Angle) * (float)(0.0025 * PhysicsConstants.PhysFactor); - movementData.AngleSpeed *= data.Damping; + movement.AngleSpeed -= math.sin(movement.Angle) * (float)(0.0025 * PhysicsConstants.PhysFactor); + movement.AngleSpeed *= state.Damping; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs index 73e744003..48ce7fe77 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs @@ -214,7 +214,7 @@ internal SurfaceState CreateState() return default; } - return new SurfaceState(gameObject.GetInstanceID(), new LineSlingshotData { + return new SurfaceState(gameObject.GetInstanceID(), new LineSlingshotState { IsDisabled = false, Threshold = collComponent.SlingshotThreshold, }); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs index 5150c1b2a..4213e4550 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceState.cs @@ -19,9 +19,9 @@ namespace VisualPinball.Unity internal struct SurfaceState { internal readonly int ItemId; - internal LineSlingshotData Slingshot; + internal LineSlingshotState Slingshot; - public SurfaceState(int itemId, LineSlingshotData slingshot) + public SurfaceState(int itemId, LineSlingshotState slingshot) { ItemId = itemId; Slingshot = slingshot; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimation.cs index 6219a8ec6..245822b61 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimation.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimation.cs @@ -20,60 +20,60 @@ namespace VisualPinball.Unity { internal static class TriggerAnimation { - internal static void Update(ref TriggerAnimationData data, ref TriggerMovementData movementData, in TriggerStaticData staticData, + internal static void Update(ref TriggerAnimationState animation, ref TriggerMovementState movement, in TriggerStaticState staticState, float dTimeMs) { - var oldTimeMsec = data.TimeMsec < dTimeMs ? data.TimeMsec : dTimeMs; - data.TimeMsec = dTimeMs; + var oldTimeMsec = animation.TimeMsec < dTimeMs ? animation.TimeMsec : dTimeMs; + animation.TimeMsec = dTimeMs; var diffTimeMsec = dTimeMs - oldTimeMsec; - var animLimit = staticData.Shape == TriggerShape.TriggerStar ? staticData.Radius * (float)(1.0 / 5.0) : 32.0f; - if (staticData.Shape == TriggerShape.TriggerButton) { - animLimit = staticData.Radius * (float)(1.0 / 10.0); + var animLimit = staticState.Shape == TriggerShape.TriggerStar ? staticState.Radius * (float)(1.0 / 5.0) : 32.0f; + if (staticState.Shape == TriggerShape.TriggerButton) { + animLimit = staticState.Radius * (float)(1.0 / 10.0); } - if (staticData.Shape == TriggerShape.TriggerWireC) { + if (staticState.Shape == TriggerShape.TriggerWireC) { animLimit = 60.0f; } - if (staticData.Shape == TriggerShape.TriggerWireD) { + if (staticState.Shape == TriggerShape.TriggerWireD) { animLimit = 25.0f; } - var limit = animLimit * staticData.TableScaleZ; + var limit = animLimit * staticState.TableScaleZ; - if (data.HitEvent) { - data.DoAnimation = true; - data.HitEvent = false; + if (animation.HitEvent) { + animation.DoAnimation = true; + animation.HitEvent = false; // unhitEvent = false; // Bugfix: If HitEvent and unhitEvent happen at the same time, you want to favor the unhit, otherwise the switch gets stuck down. - movementData.HeightOffset = 0.0f; - data.MoveDown = true; + movement.HeightOffset = 0.0f; + animation.MoveDown = true; } - if (data.UnHitEvent) { - data.DoAnimation = true; - data.UnHitEvent = false; - data.HitEvent = false; - movementData.HeightOffset = limit; - data.MoveDown = false; + if (animation.UnHitEvent) { + animation.DoAnimation = true; + animation.UnHitEvent = false; + animation.HitEvent = false; + movement.HeightOffset = limit; + animation.MoveDown = false; } - if (data.DoAnimation) { - var step = diffTimeMsec * staticData.AnimSpeed * staticData.TableScaleZ; - if (data.MoveDown) { + if (animation.DoAnimation) { + var step = diffTimeMsec * staticState.AnimSpeed * staticState.TableScaleZ; + if (animation.MoveDown) { step = -step; } - movementData.HeightOffset += step; + movement.HeightOffset += step; - if (data.MoveDown) { - if (movementData.HeightOffset <= -limit) { - movementData.HeightOffset = -limit; - data.DoAnimation = false; - data.MoveDown = false; + if (animation.MoveDown) { + if (movement.HeightOffset <= -limit) { + movement.HeightOffset = -limit; + animation.DoAnimation = false; + animation.MoveDown = false; } } else { - if (movementData.HeightOffset >= 0.0f) { - movementData.HeightOffset = 0.0f; - data.DoAnimation = false; - data.MoveDown = true; + if (movement.HeightOffset >= 0.0f) { + movement.HeightOffset = 0.0f; + animation.DoAnimation = false; + animation.MoveDown = true; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationState.cs similarity index 92% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationState.cs index c6207ebf2..aa1594e03 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct TriggerAnimationData + internal struct TriggerAnimationState { public bool HitEvent; public bool UnHitEvent; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerAnimationState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs index 212a24bde..131749c67 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs @@ -25,20 +25,20 @@ internal static class TriggerCollider { public static void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, ref CollisionEventData collEvent, ref InsideOfs insideOfs, - ref TriggerAnimationData animationData, in Collider coll) + ref TriggerAnimationState animation, in Collider coll) { var insideOf = insideOfs.IsInsideOf(coll.ItemId, ball.Id); if (collEvent.HitFlag == insideOf) { // Hit == NotAlreadyHit ball.Position += PhysicsConstants.StaticTime * ball.Velocity; // move ball slightly forward if (!insideOf) { insideOfs.SetInsideOf(coll.ItemId, ball.Id); - animationData.HitEvent = true; + animation.HitEvent = true; events.Enqueue(new EventData(EventId.HitEventsHit, coll.ItemId, ball.Id, true)); } else { insideOfs.SetOutsideOf(coll.ItemId, ball.Id); - animationData.UnHitEvent = true; + animation.UnHitEvent = true; events.Enqueue(new EventData(EventId.HitEventsUnhit, coll.ItemId, ball.Id, true)); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs index 54e59b08c..a7a186ea9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs @@ -260,14 +260,14 @@ internal TriggerState CreateState() return new TriggerState( gameObject.GetInstanceID(), animComponent ? animComponent.gameObject.GetInstanceID() : 0, - new TriggerStaticData { + new TriggerStaticState { AnimSpeed = animComponent.AnimSpeed, Radius = collComponent.HitCircleRadius, Shape = meshComponent.Shape, TableScaleZ = 1f }, - new TriggerMovementData(), - new TriggerAnimationData() + new TriggerMovementState(), + new TriggerAnimationState() ); } @@ -292,13 +292,13 @@ internal TriggerState CreateState() return new TriggerState( gameObject.GetInstanceID(), - new TriggerStaticData { + new TriggerStaticState { AnimSpeed = 0, Radius = collComponent.HitCircleRadius, Shape = TriggerShape.TriggerNone, TableScaleZ = 1f }, - new FlipperCorrectionData { + new FlipperCorrectionState { IsEnabled = true, Value = blobAssetRef } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementState.cs similarity index 92% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementState.cs index 472a5e5e8..67680787a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct TriggerMovementData + internal struct TriggerMovementState { public float HeightOffset; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerMovementState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs index 1e8e9781f..afa9e8289 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs @@ -20,15 +20,15 @@ internal struct TriggerState { internal readonly int ItemId; internal readonly int AnimatedItemId; - internal TriggerStaticData Static; - internal TriggerMovementData Movement; - internal TriggerAnimationData Animation; - internal FlipperCorrectionData FlipperCorrection; + internal TriggerStaticState Static; + internal TriggerMovementState Movement; + internal TriggerAnimationState Animation; + internal FlipperCorrectionState FlipperCorrection; /// /// Default trigger usage. /// - public TriggerState(int itemId, int animatedItemId, TriggerStaticData @static, TriggerMovementData movement, TriggerAnimationData animation) + public TriggerState(int itemId, int animatedItemId, TriggerStaticState @static, TriggerMovementState movement, TriggerAnimationState animation) { ItemId = itemId; AnimatedItemId = animatedItemId; @@ -41,7 +41,7 @@ public TriggerState(int itemId, int animatedItemId, TriggerStaticData @static, T /// /// Flipper correction usage. /// - public TriggerState(int itemId, TriggerStaticData @static, FlipperCorrectionData flipperCorrection) + public TriggerState(int itemId, TriggerStaticState @static, FlipperCorrectionState flipperCorrection) { ItemId = itemId; AnimatedItemId = 0; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticState.cs similarity index 93% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticState.cs index 2c9342a36..ecf610673 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticState.cs @@ -16,7 +16,7 @@ namespace VisualPinball.Unity { - internal struct TriggerStaticData + internal struct TriggerStaticState { public int Shape; public float Radius; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerStaticState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs index 427769c4d..76af397dc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs @@ -25,12 +25,12 @@ internal static class TriggerTransform { private static readonly Dictionary _initialOffset = new(); - internal static void Update(int itemId, in TriggerMovementData data, Transform transform) + internal static void Update(int itemId, in TriggerMovementState movement, Transform transform) { var worldPos = transform.position; _initialOffset.TryAdd(itemId, worldPos.y); - worldPos.y = _initialOffset[itemId] + Physics.ScaleToWorld(data.HeightOffset); + worldPos.y = _initialOffset[itemId] + Physics.ScaleToWorld(movement.HeightOffset); transform.position = worldPos; } } From a4781d5ea3f8782748a2ac3b6299356563c2aed0 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 22:21:37 +0200 Subject: [PATCH 111/159] jobs: Fix playfield and physics engine availability in player. --- .../VisualPinball.Unity/Game/Player.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index d5f59cd8e..cf00e96a9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -35,7 +35,7 @@ public class Player : MonoBehaviour public PlayfieldApi PlayfieldApi { get; private set; } // shortcuts - public GameObject Playfield => _playfieldComponent.gameObject; + public GameObject Playfield => PlayfieldComponent.gameObject; [NonSerialized] public IGamelogicEngine GamelogicEngine; @@ -90,6 +90,15 @@ public class Player : MonoBehaviour private PlayfieldComponent _playfieldComponent; private PhysicsEngine _physicsEngine; + private PlayfieldComponent PlayfieldComponent { + get { + if (_playfieldComponent == null) { + _playfieldComponent = GetComponentInChildren(); + } + return _playfieldComponent; + } + } + private PhysicsEngine PhysicsEngine { get { if (_physicsEngine == null) { @@ -111,7 +120,7 @@ private PhysicsEngine PhysicsEngine { public Dictionary CoilStatuses => _coilPlayer.CoilStatuses; public Dictionary LampStatuses => _lampPlayer.LampStates; public Dictionary WireStatuses => _wirePlayer.WireStatuses; - public float3 Gravity => _playfieldComponent.Gravity; + public float3 Gravity => PlayfieldComponent.Gravity; public int NextBallId => ++_currentBallId; private int _currentBallId; @@ -133,7 +142,6 @@ private void Awake() { DebugLogger.ClearLog(); _tableComponent = GetComponent(); - _playfieldComponent = GetComponentInChildren(); var engineComponent = GetComponent(); _apis.Add(TableApi); From d931f67ab8a92c8c9bfdced50a32d071314642ff Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 22:45:48 +0200 Subject: [PATCH 112/159] jobs: Fix ball roller. --- .../Game/BallRollerComponent.cs | 52 +++++++++---------- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 1 + 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs index 5a7837c0d..a48866eae 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs @@ -14,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Collections; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using UnityEngine.InputSystem; @@ -24,15 +22,14 @@ namespace VisualPinball.Unity { public class BallRollerComponent : MonoBehaviour { + private PhysicsEngine _physicsEngine; private PlayfieldComponent _playfield; private Matrix4x4 _ltw; private Matrix4x4 _wtl; private Plane _playfieldPlane; - private EntityManager _entityManager; - private Entity _ballEntity = Entity.Null; - private EntityQuery _ballEntityQuery; + private int _ballId = 0; private void Awake() { @@ -46,9 +43,7 @@ private void Awake() var p2 = _ltw.MultiplyPoint(new Vector3(100f, 100f, z)); var p3 = _ltw.MultiplyPoint(new Vector3(100f, -100f, z)); _playfieldPlane.Set3Points(p1, p2, p3); - - _entityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - _ballEntityQuery = _entityManager.CreateEntityQuery(typeof(BallState)); + _physicsEngine = GetComponentInParent(); } private void Update() @@ -60,21 +55,24 @@ private void Update() // find nearest ball if (Mouse.current.middleButton.wasPressedThisFrame) { if (GetCursorPositionOnPlayfield(out var mousePosition)) { - var ballEntities = _ballEntityQuery.ToEntityArray(Allocator.Temp); var nearestDistance = float.PositiveInfinity; BallState nearestBall = default; var ballFound = false; - foreach (var ballEntity in ballEntities) { - var ballData = _entityManager.GetComponentData(ballEntity); - if (ballData.IsFrozen) { - continue; - } - var distance = math.distance(mousePosition, ballData.Position.xy); - if (distance < nearestDistance) { - nearestDistance = distance; - nearestBall = ballData; - ballFound = true; - _ballEntity = ballEntity; + + using (var enumerator = _physicsEngine.Balls.GetEnumerator()) { + while (enumerator.MoveNext()) { + var ball = enumerator.Current.Value; + + if (ball.IsFrozen) { + continue; + } + var distance = math.distance(mousePosition, ball.Position.xy); + if (distance < nearestDistance) { + nearestDistance = distance; + nearestBall = ball; + ballFound = true; + _ballId = ball.Id; + } } } @@ -83,18 +81,17 @@ private void Update() } } - } else if (Mouse.current.middleButton.isPressed && _ballEntity != Entity.Null) { + } else if (Mouse.current.middleButton.isPressed && _ballId != 0) { if (GetCursorPositionOnPlayfield(out var mousePosition)) { - var ballData = _entityManager.GetComponentData(_ballEntity); - UpdateBall(ref ballData, mousePosition); + ref var ball = ref _physicsEngine.BallState(_ballId); + UpdateBall(ref ball, mousePosition); } } - if (Mouse.current.middleButton.wasReleasedThisFrame && _ballEntity != Entity.Null) { - var ballData = _entityManager.GetComponentData(_ballEntity); + if (Mouse.current.middleButton.wasReleasedThisFrame && _ballId != 0) { + ref var ballData = ref _physicsEngine.BallState(_ballId); ballData.ManualControl = false; - _entityManager.SetComponentData(_ballEntity, ballData); - _ballEntity = Entity.Null; + _ballId = 0; } } @@ -102,7 +99,6 @@ private void UpdateBall(ref BallState ballState, float2 position) { ballState.ManualControl = true; ballState.ManualPosition = position; - _entityManager.SetComponentData(_ballEntity, ballState); } private bool GetCursorPositionOnPlayfield(out float2 position) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 09efab71c..feb032223 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -82,6 +82,7 @@ public void ScheduleAction(uint timeoutMs, Action action) internal delegate void InputAction(ref PhysicsState state); + internal ref NativeParallelHashMap Balls => ref _ballStates; internal void Schedule(InputAction action) => _inputActions.Enqueue(action); internal ref BallState BallState(int itemId) => ref _ballStates.GetValueByRef(itemId); internal ref BumperState BumperState(int itemId) => ref _bumperStates.GetValueByRef(itemId); From 7982744effacf5ba2d617fdef7c0440daaab5185 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 15 Oct 2023 23:36:07 +0200 Subject: [PATCH 113/159] cleanup: Remove components, quadtree, octree and entities where possible. --- .../VPT/Primitive/PrimitiveInspector.cs | 1 - .../VisualPinball.Unity/Game/PhysicsCycle.cs | 1 - .../VisualPinball.Unity/Game/PhysicsEngine.cs | 1 - .../Game/PhysicsUpdateJob.cs | 1 - .../VisualPinball.Unity/Game/SwitchHandler.cs | 3 - .../Game/SystemBaseStub.cs | 41 --- .../Game/SystemBaseStub.cs.meta | 3 - .../VisualPinballAutomaticWorldBootstrap.cs | 38 -- ...sualPinballAutomaticWorldBootstrap.cs.meta | 11 - .../Physics/Collider/CircleCollider.cs | 2 - .../Physics/Collider/Collider.cs | 47 +-- .../Physics/Collider/ColliderInfo.cs | 1 - .../Physics/Collider/LineCollider.cs | 4 +- .../Physics/Collision/BallColliderBounds.cs | 37 -- .../Collision/BallColliderBounds.cs.meta | 11 - .../Physics/Collision/ColliderBounds.cs | 4 +- .../Physics/Collision/ColliderHeader.cs | 1 - .../Physics/Collision/CollisionEventData.cs | 3 +- .../{ContactSystem.cs => ContactPhysics.cs} | 4 +- ...tSystem.cs.meta => ContactPhysics.cs.meta} | 0 .../Physics/Collision/KdNode.cs | 335 ------------------ .../Physics/Collision/KdNode.cs.meta | 11 - .../Physics/Collision/KdRoot.cs | 103 ------ .../Physics/Collision/KdRoot.cs.meta | 11 - .../OverlappingDynamicBufferElement.cs | 36 -- .../OverlappingDynamicBufferElement.cs.meta | 11 - .../OverlappingStaticBufferElement.cs | 26 -- .../OverlappingStaticBufferElement.cs.meta | 11 - .../Physics/Collision/PhysicsMaterialData.cs | 3 +- .../Physics/Collision/QuadTree.cs | 255 ------------- .../Physics/Collision/QuadTree.cs.meta | 11 - .../Physics/Collision/QuadTreeBlob.cs | 23 -- .../Physics/Collision/QuadTreeBlob.cs.meta | 11 - .../Physics/Collision/QuadTreeCreator.cs | 99 ------ .../Physics/Collision/QuadTreeCreator.cs.meta | 11 - .../Physics/Collision/QuadTreeData.cs | 25 -- .../Physics/Collision/QuadTreeData.cs.meta | 11 - .../Physics/Event/EventData.cs | 1 - .../VisualPinball.Unity/VPT/Ball/BallApi.cs | 34 -- .../VPT/Ball/BallApi.cs.meta | 11 - .../VPT/Ball/BallDisplacementPhysics.cs | 3 +- .../VPT/Ball/BallInsideOfBufferElement.cs | 30 -- .../Ball/BallInsideOfBufferElement.cs.meta | 11 - .../VPT/Ball/BallMovementPhysics.cs | 5 +- .../VPT/Ball/BallSpinHackPhysics.cs | 5 +- .../VisualPinball.Unity/VPT/Ball/BallState.cs | 18 +- .../VPT/Ball/BallVelocityPhysics.cs | 3 +- .../VisualPinball.Unity/VPT/EventArgs.cs | 2 - .../VPT/Flipper/FlipperApi.cs | 3 - .../VPT/Flipper/FlipperColliderComponent.cs | 2 - .../VPT/Flipper/FlipperComponent.cs | 2 +- .../VPT/Flipper/FlipperCorrection.cs | 2 +- .../VPT/Flipper/FlipperCorrectionState.cs | 2 +- .../VPT/Flipper/FlipperDisplacementPhysics.cs | 3 +- .../VPT/Flipper/FlipperHitData.cs | 3 +- .../VPT/Flipper/FlipperMovementState.cs | 3 +- .../VPT/Flipper/FlipperState.cs | 4 +- .../VPT/Flipper/FlipperStaticData.cs | 3 +- .../VPT/Flipper/FlipperTricksData.cs | 5 +- .../VPT/Flipper/FlipperVelocityData.cs | 4 +- .../VPT/Flipper/FlipperVelocityPhysics.cs | 3 +- ...{SolenoidStateData.cs => SolenoidState.cs} | 4 +- ...tateData.cs.meta => SolenoidState.cs.meta} | 0 .../VisualPinball.Unity/VPT/Gate/GateApi.cs | 2 - .../VPT/Gate/GateColliderComponent.cs | 2 - .../VPT/Gate/GateDisplacementPhysics.cs | 3 +- .../VPT/Gate/GateVelocityPhysics.cs | 3 +- .../VPT/HitTarget/DropTargetAnimation.cs | 3 +- .../VPT/HitTarget/HitTargetAnimation.cs | 4 +- .../HitTarget/HitTargetColliderComponent.cs | 2 - .../VisualPinball.Unity/VPT/IApi.cs | 2 - .../VPT/Kicker/KickerCollider.cs | 2 - .../VPT/Kicker/KickerColliderComponent.cs | 2 - .../VPT/Kicker/KickerCollisionState.cs | 4 +- .../VPT/Kicker/KickerStaticState.cs | 3 +- .../MetalWireGuideColliderComponent.cs | 2 - .../VPT/Playfield/PlayfieldComponent.cs | 2 - .../VPT/Plunger/PlungerAnimation.cs | 3 +- .../VPT/Plunger/PlungerColliderComponent.cs | 2 - .../VPT/Plunger/PlungerDisplacementPhysics.cs | 3 +- .../VPT/Plunger/PlungerVelocityPhysics.cs | 3 +- .../VPT/Ramp/RampColliderComponent.cs | 2 - .../VPT/Rubber/RubberColliderComponent.cs | 2 - .../VPT/Spinner/SpinnerApi.cs | 2 - .../VPT/Spinner/SpinnerColliderComponent.cs | 2 - .../VPT/Spinner/SpinnerDisplacementPhysics.cs | 3 +- .../VPT/Spinner/SpinnerVelocityPhysics.cs | 3 +- .../VPT/Surface/SurfaceColliderComponent.cs | 2 - .../VPT/Teleporter/TeleporterApi.cs | 4 +- .../VPT/Trigger/TriggerColliderComponent.cs | 1 - .../VPT/Trigger/TriggerTransform.cs | 4 +- 91 files changed, 38 insertions(+), 1407 deletions(-) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballAutomaticWorldBootstrap.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballAutomaticWorldBootstrap.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/BallColliderBounds.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/BallColliderBounds.cs.meta rename VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/{ContactSystem.cs => ContactPhysics.cs} (94%) rename VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/{ContactSystem.cs.meta => ContactPhysics.cs.meta} (100%) delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingDynamicBufferElement.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingDynamicBufferElement.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingStaticBufferElement.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingStaticBufferElement.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeBlob.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeBlob.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeData.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeData.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallApi.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallApi.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs.meta rename VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/{SolenoidStateData.cs => SolenoidState.cs} (88%) rename VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/{SolenoidStateData.cs.meta => SolenoidState.cs.meta} (100%) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/Primitive/PrimitiveInspector.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/Primitive/PrimitiveInspector.cs index d552440b8..7ebc8219a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/Primitive/PrimitiveInspector.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/Primitive/PrimitiveInspector.cs @@ -17,7 +17,6 @@ // ReSharper disable AssignmentInConditionalExpression using System.Linq; -using Unity.Entities; using UnityEditor; using UnityEngine; using VisualPinball.Engine.VPT.Primitive; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index 49fee3154..c91c1d8f6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -20,7 +20,6 @@ using Unity.Profiling; using VisualPinball.Engine.Common; using VisualPinball.Unity.Collections; -using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index feb032223..8d14e5672 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -23,7 +23,6 @@ using Unity.Mathematics; using UnityEngine; using VisualPinball.Unity.Collections; -using VisualPinballUnity; using AABB = NativeTrees.AABB; using Debug = UnityEngine.Debug; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs index 4b77a37cf..e1e28fa8e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs @@ -19,7 +19,6 @@ using Unity.Entities; using Unity.Jobs; using VisualPinball.Engine.Common; -using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs index a616d237a..b68b6d66b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/SwitchHandler.cs @@ -17,11 +17,8 @@ using System; using System.Collections.Generic; using NLog; -using Unity.Entities; using UnityEngine; -using VisualPinballUnity; using Logger = NLog.Logger; - #if UNITY_EDITOR using UnityEditor; #endif diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs deleted file mode 100644 index e9e8905c3..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Unity.Entities; -using Unity.Entities.CodeGeneratedJobForEach; - -namespace VisualPinball.Unity.VisualPinball.Unity.Game -{ - public abstract class SystemBaseStub - { - protected abstract void OnUpdate(); - protected virtual void OnCreate() { } - protected virtual void OnStartRunning() { } - protected virtual void OnDestroy() { } - - public void Update() { } - - public ComponentLookup GetComponentLookup(bool isReadOnly = false) where T : unmanaged, IComponentData => default; - - public T GetComponentData(Entity entity) where T : unmanaged, IComponentData => default; - - public EntityManager EntityManager => default; - - public World World => default; - - protected internal LambdaSingleJobDescription Job => new LambdaSingleJobDescription(); - - protected internal T GetComponent(Entity entity) where T : unmanaged, IComponentData => EntityManager.GetComponentData(entity); - protected internal T GetComponent(int itemId) where T : unmanaged, IComponentData => default; - - protected internal void SetComponent(Entity entity, T component) where T : unmanaged, IComponentData => EntityManager.SetComponentData(entity, component); - - protected internal void SetComponent(int itemId, T component) where T : unmanaged, IComponentData { } - - protected internal bool HasComponent(Entity entity) where T : unmanaged, IComponentData => false; - protected internal bool HasComponent(int itemId) where T : unmanaged, IComponentData => false; - - protected internal EntityQuery GetEntityQuery(params ComponentType[] componentTypes) => default; - - protected internal ForEachLambdaJobDescription Entities => new ForEachLambdaJobDescription(); - - public new BufferLookup GetBufferLookup(bool isReadOnly = false) where T : unmanaged, IBufferElementData => default; - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs.meta deleted file mode 100644 index 5d73a3ae2..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/SystemBaseStub.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c49f3b7a47af43d68216e6545ed8c13b -timeCreated: 1675516205 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballAutomaticWorldBootstrap.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballAutomaticWorldBootstrap.cs deleted file mode 100644 index 46fe9dcb8..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballAutomaticWorldBootstrap.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -// https://forum.unity.com/threads/got-nullreferenceexception-from-automaticworldbootstrap-initialize.1075933/#post-7132262 -// https://github.com/freezy/VisualPinball.Engine/issues/371 - -#if UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP - -using Unity.Entities; -using UnityEngine; - -namespace VisualPinball.Unity -{ - static class VisualPinballAutomaticWorldBootstrap - { - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] - static void Initialize() - { - DefaultWorldInitialization.Initialize("Default World", false); - //GameObjectSceneUtility.AddGameObjectSceneReferences(); - } - } -} - -#endif diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballAutomaticWorldBootstrap.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballAutomaticWorldBootstrap.cs.meta deleted file mode 100644 index c6bcf44b8..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/VisualPinballAutomaticWorldBootstrap.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e9b4ba602429a4aadaa2d69d71d900a5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs index f4024fd65..d8bd385cb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs @@ -14,13 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; using VisualPinball.Engine.VPT; -using Random = Unity.Mathematics.Random; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 3f692b00b..1ad3390e8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -28,7 +28,7 @@ namespace VisualPinball.Unity /// Base struct common to all colliders. /// Dispatches the interface methods to appropriate implementations for the collider type. /// - public struct Collider : IComponentData + public struct Collider { public ColliderHeader Header; @@ -81,51 +81,6 @@ public unsafe ColliderBounds Bounds() { } } - internal static unsafe float HitTest(ref Collider coll, ref CollisionEventData collEvent, - ref DynamicBuffer insideOf, in BallState ball, float dTime) - { - fixed (Collider* collider = &coll) - { - switch (collider->Type) - { - case ColliderType.Bumper: - case ColliderType.Circle: -// return ((CircleCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); - case ColliderType.Gate: -// return ((GateCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); - case ColliderType.Line: -// return ((LineCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); - case ColliderType.LineZ: - // return ((LineZCollider*) collider)->HitTest(ref collEvent, in ball, dTime); - case ColliderType.Line3D: - // return ((Line3DCollider*) collider)->HitTest(ref collEvent, in ball, dTime); - case ColliderType.Point: - // return ((PointCollider*) collider)->HitTest(ref collEvent, in ball, dTime); - case ColliderType.Plane: - return ((PlaneCollider*) collider)->HitTest(ref collEvent, in ball, dTime); - case ColliderType.Spinner: -// return ((SpinnerCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); - case ColliderType.Triangle: -// return ((TriangleCollider*) collider)->HitTest(ref collEvent, in insideOf, in ball, dTime); - case ColliderType.KickerCircle: - case ColliderType.TriggerCircle: -// return ((CircleCollider*) collider)->HitTestBasicRadius(ref collEvent, ref insideOf, in ball, dTime, false, false, false); - case ColliderType.TriggerLine: -// return ((LineCollider*) collider)->HitTestBasic(ref collEvent, ref insideOf, in ball, dTime, false, false, false); - - case ColliderType.Plunger: - throw new InvalidOperationException("ColliderType.Plunger must be hit-tested separately!"); - case ColliderType.Flipper: - throw new InvalidOperationException("ColliderType.Flipper must be hit-tested separately!"); - case ColliderType.LineSlingShot: - throw new InvalidOperationException("ColliderType.LineSlingShot must be hit-tested separately!"); - - default: - return -1; - } - } - } - internal static unsafe float HitTest(in Collider coll, ref CollisionEventData collEvent, in BallState ball, float dTime) { fixed (Collider* collider = &coll) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs index bf860f531..336d86ffc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderInfo.cs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using VisualPinball.Engine.VPT; namespace VisualPinball.Unity diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index 954a1e4b2..7ceadb240 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -18,10 +18,8 @@ using Unity.Collections.LowLevel.Unsafe; using Unity.Entities; using Unity.Mathematics; -using UnityEngine; using VisualPinball.Engine.Common; using VisualPinball.Engine.VPT; -using Random = Unity.Mathematics.Random; namespace VisualPinball.Unity { @@ -72,7 +70,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray, BlobPtr>(ref colliders[_header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), + UnsafeUtility.AddressOf(ref collider), UnsafeUtility.AddressOf(ref this), sizeof(LineCollider) ); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/BallColliderBounds.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/BallColliderBounds.cs deleted file mode 100644 index eee4535e6..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/BallColliderBounds.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinball.Unity -{ - internal struct BallColliderBounds - { - public Entity BallEntity; - public Aabb Aabb; - - public BallColliderBounds(Entity ballEntity, Aabb aabb) - { - BallEntity = ballEntity; - Aabb = aabb; - } - - public override string ToString() - { - return $"{Aabb.ToString()} ({BallEntity})"; - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/BallColliderBounds.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/BallColliderBounds.cs.meta deleted file mode 100644 index 5d42d56d1..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/BallColliderBounds.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7d7fc699a55b785449dae32e78168bcb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs index 709ac06f8..58460f446 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBounds.cs @@ -15,7 +15,7 @@ // along with this program. If not, see . using System; -using Unity.Entities; +using NativeTrees; namespace VisualPinball.Unity { @@ -36,7 +36,7 @@ public ColliderBounds(int itemId, int colliderId, Aabb aabb) Aabb = aabb; } - public static implicit operator NativeTrees.AABB(ColliderBounds b) => b.Aabb; + public static implicit operator AABB(ColliderBounds b) => b.Aabb; public override string ToString() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs index 17192cf5a..101592517 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs @@ -15,7 +15,6 @@ // along with this program. If not, see . using System; -using Unity.Entities; using VisualPinball.Engine.VPT; namespace VisualPinball.Unity diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs index 410ee093e..83ed4b55a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/CollisionEventData.cs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; namespace VisualPinball.Unity { - internal struct CollisionEventData : IComponentData + internal struct CollisionEventData { public float HitTime; public float3 HitNormal; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs similarity index 94% rename from VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs rename to VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs index b724da2bf..f00836a60 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using VisualPinball.Unity; - -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class ContactPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactSystem.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs deleted file mode 100644 index eb7e3917d..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs +++ /dev/null @@ -1,335 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; - -namespace VisualPinball.Unity -{ - internal struct KdNode - { - public Aabb Bounds; // m_rectbounds - public int Start; // m_start - - /// - /// Contains the 2 bits for axis (bits 30/31) - /// - public int Items; // m_items - - /// - /// If NULL, is a leaf; otherwise keeps the 2 children - /// - private int _childA; // m_children - private int _childB; - - private bool HasChildren => _childA > -1 && _childB > -1; - - public KdNode(Aabb bounds) - { - Bounds = bounds; - Start = 0; - Items = 2; - _childA = -1; - _childB = -1; - } - - public void Reset() - { - _childA = -1; - _childB = -1; - Start = 0; - Items = 0; - } - - - public void CreateNextLevel(int level, int levelEmpty, KdRoot hitOct) { - var orgItems = Items & 0x3FFFFFFF; - - // !! magic - if (orgItems <= 4 || level >= 128 / 2) { - return; - } - - var vDiag = new float3( - Bounds.Right - Bounds.Left, - Bounds.Bottom - Bounds.Top, - Bounds.ZHigh - Bounds.ZLow - ); - - int axis; - if (vDiag.x > vDiag.y && vDiag.x > vDiag.z) { - if (vDiag.x < 0.0001) { - return; - } - axis = 0; - - } else if (vDiag.y > vDiag.z) { - if (vDiag.y < 0.0001) { - return; - } - axis = 1; - - } else { - if (vDiag.z < 0.0001) { - return; - } - axis = 2; - } - - //!! weight this with ratio of elements going to middle vs left&right! (avoids volume split that goes directly through object) - - // create children - if (!hitOct.HasNodesAvailable()) { - // ran out of nodes - abort - return; - } - - var childA = new KdNode(Bounds); - var childB = new KdNode(Bounds); - - var vCenter = new float3( - (Bounds.Left + Bounds.Right) * 0.5f, - (Bounds.Top + Bounds.Bottom) * 0.5f, - (Bounds.ZLow + Bounds.ZHigh) * 0.5f - ); - switch (axis) { - case 0: - childA.Bounds.Right = vCenter.x; - childB.Bounds.Left = vCenter.x; - break; - case 1: - childA.Bounds.Bottom = vCenter.y; - childB.Bounds.Top = vCenter.y; - break; - default: - childA.Bounds.ZHigh = vCenter.z; - childB.Bounds.ZLow = vCenter.z; - break; - } - - childA.Reset(); - childB.Reset(); - - // determine amount of items that cross splitplane, or are passed on to the children - if (axis == 0) { - for (var i = Start; i < Start + orgItems; ++i) { - var bounds = hitOct.GetItemAt(i); - - if (bounds.Aabb.Right < vCenter.x) { - childA.Items++; - - } else if (bounds.Aabb.Left > vCenter.x) { - childB.Items++; - } - } - - } else if (axis == 1) { - for (var i = Start; i < Start + orgItems; ++i) { - var bounds = hitOct.GetItemAt(i); - - if (bounds.Aabb.Bottom < vCenter.y) { - childA.Items++; - - } else if (bounds.Aabb.Top > vCenter.y) { - childB.Items++; - } - } - - } else { - // axis == 2 - for (var i = Start; i < Start + orgItems; ++i) { - var bounds = hitOct.GetItemAt(i); - - if (bounds.Aabb.ZHigh < vCenter.z) { - childA.Items++; - - } else if (bounds.Aabb.ZLow > vCenter.z) { - childB.Items++; - } - } - } - - // check if at least two nodes feature objects, otherwise don"t bother subdividing further - var countEmpty = 0; - if (childA.Items == 0) { - countEmpty = 1; - } - - if (childB.Items == 0) { - ++countEmpty; - } - - if (orgItems - childA.Items - childB.Items == 0) { - ++countEmpty; - } - - if (countEmpty >= 2) { - ++levelEmpty; - - } else { - levelEmpty = 0; - } - - if (levelEmpty > 8) { - // If 8 levels were all just subdividing the same objects without luck, exit & Free the nodes again (but at least empty space was cut off) - // no need to update NumNodes, since we didn't increment them yet. - _childA = -1; - _childB = -1; - return; - } - - childA.Start = Start + orgItems - childA.Items - childB.Items; - childB.Start = childA.Start + childA.Items; - - var items = 0; - childA.Items = 0; - childB.Items = 0; - - switch (axis) { - - // sort items that cross splitplane in-place, the others are sorted into a temporary - case 0: { - for (var i = Start; i < Start + orgItems; ++i) { - var bounds = hitOct.GetItemAt(i); - - if (bounds.Aabb.Right < vCenter.x) { - hitOct.Indices[childA.Start + childA.Items++] = hitOct.OrgIdx[i]; - - } else if (bounds.Aabb.Left > vCenter.x) { - hitOct.Indices[childB.Start + childB.Items++] = hitOct.OrgIdx[i]; - - } else { - hitOct.OrgIdx[Start + items++] = hitOct.OrgIdx[i]; - } - } - break; - } - - case 1: { - for (var i = Start; i < Start + orgItems; ++i) { - var bounds = hitOct.GetItemAt(i); - - if (bounds.Aabb.Bottom < vCenter.y) { - hitOct.Indices[childA.Start + childA.Items++] = hitOct.OrgIdx[i]; - - } else if (bounds.Aabb.Top > vCenter.y) { - hitOct.Indices[childB.Start + childB.Items++] = hitOct.OrgIdx[i]; - - } else { - hitOct.OrgIdx[Start + items++] = hitOct.OrgIdx[i]; - } - } - break; - } - - default: { // axis == 2 - - for (var i = Start; i < Start + orgItems; ++i) { - var bounds = hitOct.GetItemAt(i); - - if (bounds.Aabb.ZHigh < vCenter.z) { - hitOct.Indices[childA.Start + childA.Items++] = hitOct.OrgIdx[i]; - - } else if (bounds.Aabb.ZLow > vCenter.z) { - hitOct.Indices[childB.Start + childB.Items++] = hitOct.OrgIdx[i]; - - } else { - hitOct.OrgIdx[Start + items++] = hitOct.OrgIdx[i]; - } - } - break; - } - } - - // The following assertions hold after this step: - //assert( this.Start + items == this.Children[0].This.Start ); - //assert( this.Children[0].This.Start + this.Children[0].This.Items == this.Children[1].This.Start ); - //assert( this.Children[1].This.Start + this.Children[1].This.Items == this.Start + org_items ); - //assert( this.Start + org_items <= this.HitOct->tmp.Size() ); - - Items = items | (axis << 30); - - // copy temporary back //!! could omit this by doing everything inplace - for (var i = 0; i < childA.Items; i++) { - hitOct.OrgIdx[childA.Start + i] = hitOct.Indices[childA.Start + i]; - } - for (var i = 0; i < childB.Items; i++) { - hitOct.OrgIdx[childB.Start + i] = hitOct.Indices[childB.Start + i]; - } - - hitOct.AddNodes(childA, childB, out _childA, out _childB); - - childA.CreateNextLevel(level + 1, levelEmpty, hitOct); - childB.CreateNextLevel(level + 1, levelEmpty, hitOct); - } - - public void GetAabbOverlaps(ref KdRoot hitOct, in Entity entity, in BallState ball, ref DynamicBuffer overlappingEntities) { - - var orgItems = Items & 0x3FFFFFFF; - var axis = Items >> 30; - var bounds = ball.Aabb; - var collisionRadiusSqr = ball.CollisionRadiusSqr; - - for (var i = Start; i < Start + orgItems; i++) { - var b = hitOct.GetItemAt(i); - if (entity != b.BallEntity && b.Aabb.IntersectSphere(ball.Position, collisionRadiusSqr)) { - overlappingEntities.Add(b.BallEntity); - } - } - - if (HasChildren) { - switch (axis) { - // not a leaf - case 0: { - var vCenter = (Bounds.Left + Bounds.Right) * 0.5f; - if (bounds.Left <= vCenter) { - hitOct.GetNodeAt(_childA).GetAabbOverlaps(ref hitOct, in entity, in ball, ref overlappingEntities); - } - - if (bounds.Right >= vCenter) { - hitOct.GetNodeAt(_childB).GetAabbOverlaps(ref hitOct, in entity, in ball, ref overlappingEntities); - } - break; - } - - case 1: { - var vCenter = (Bounds.Top + Bounds.Bottom) * 0.5f; - if (bounds.Top <= vCenter) { - hitOct.GetNodeAt(_childA).GetAabbOverlaps(ref hitOct, in entity, in ball, ref overlappingEntities); - } - - if (bounds.Bottom >= vCenter) { - hitOct.GetNodeAt(_childB).GetAabbOverlaps(ref hitOct, in entity, in ball, ref overlappingEntities); - } - break; - } - - default: { - var vCenter = (Bounds.ZLow + Bounds.ZHigh) * 0.5f; - if (bounds.ZLow <= vCenter) { - hitOct.GetNodeAt(_childA).GetAabbOverlaps(ref hitOct, in entity, in ball, ref overlappingEntities); - } - - if (bounds.ZHigh >= vCenter) { - hitOct.GetNodeAt(_childB).GetAabbOverlaps(ref hitOct, in entity, in ball, ref overlappingEntities); - } - break; - } - } - } - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs.meta deleted file mode 100644 index d04b321ac..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdNode.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8751c1d1dcb375a4792baee9353d0f7d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs deleted file mode 100644 index 466ca9454..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using Unity.Collections; -using Unity.Entities; - -namespace VisualPinball.Unity -{ - internal struct KdRoot : IDisposable - { - public int NumNodes; // m_num_nodes - public NativeArray OrgIdx; // m_org_idx - public NativeArray Indices; // tmp - - private KdNode _rootNode; // m_rootNode - private NativeArray _bounds; // m_org_vho - private NativeArray _nodes; // m_nodes - - private int _numItems; // m_num_items - - public void Init(NativeArray bounds, Allocator allocator) - { - _bounds = bounds; - _numItems = bounds.Length; - - OrgIdx = new NativeArray(_numItems, allocator); - Indices = new NativeArray(_numItems, allocator); - _nodes = new NativeArray(_numItems * 2 + 1, allocator); - - NumNodes = 0; - _rootNode = new KdNode(); - _rootNode.Reset(); - - FillFromVector(bounds); - } - - private void FillFromVector(NativeArray bounds) - { - _rootNode.Bounds.Clear(); - _rootNode.Start = 0; - _rootNode.Items = _numItems; - - for (var i = 0; i < _numItems; ++i) { - _rootNode.Bounds.Extend(bounds[i].Aabb); - OrgIdx[i] = i; - } - - _rootNode.CreateNextLevel(0, 0, this); - } - - public void GetAabbOverlaps(in Entity entity, in BallState ball, ref DynamicBuffer overlappingEntities) - { - _rootNode.GetAabbOverlaps(ref this, in entity, in ball, ref overlappingEntities); - } - - public BallColliderBounds GetItemAt(int i) - { - return _bounds[OrgIdx[i]]; - } - - public KdNode GetNodeAt(int i) - { - return _nodes[i]; - } - - public bool HasNodesAvailable() - { - // space for two more nodes? - return NumNodes + 1 < _nodes.Length; - } - - public void AddNodes(KdNode nodeA, KdNode nodeB, out int nodeIndexA, out int nodeIndexB) - { - NumNodes += 2; - nodeIndexA = NumNodes - 2; - nodeIndexB = NumNodes - 1; - _nodes[nodeIndexA] = nodeA; - _nodes[nodeIndexB] = nodeB; - } - - public void Dispose() - { - _bounds.Dispose(); - _nodes.Dispose(); - OrgIdx.Dispose(); - Indices.Dispose(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs.meta deleted file mode 100644 index fa823cc6e..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/KdRoot.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 389ba5fd12b0d6142a5bfeaa323b8050 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingDynamicBufferElement.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingDynamicBufferElement.cs deleted file mode 100644 index 4f4dae0e7..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingDynamicBufferElement.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinball.Unity -{ - [InternalBufferCapacity(0)] - internal struct OverlappingDynamicBufferElement : IBufferElementData - { - public Entity Value; - - public static implicit operator Entity(OverlappingDynamicBufferElement e) - { - return e.Value; - } - - public static implicit operator OverlappingDynamicBufferElement(Entity e) - { - return new OverlappingDynamicBufferElement { Value = e }; - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingDynamicBufferElement.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingDynamicBufferElement.cs.meta deleted file mode 100644 index f5a7c9d48..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingDynamicBufferElement.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: eab61292d11b9324f95de2b811f19b34 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingStaticBufferElement.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingStaticBufferElement.cs deleted file mode 100644 index 05d4b43fd..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingStaticBufferElement.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinball.Unity -{ - [InternalBufferCapacity(0)] - internal struct OverlappingStaticColliderBufferElement : IBufferElementData - { - public int Value; - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingStaticBufferElement.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingStaticBufferElement.cs.meta deleted file mode 100644 index cf31261b1..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/OverlappingStaticBufferElement.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b34a0c3ee39824845996a8f36ae9e9ee -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs index 316dbabee..66c5c74ec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs @@ -15,11 +15,10 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Entities; namespace VisualPinball.Unity { - public struct PhysicsMaterialData : IComponentData + public struct PhysicsMaterialData { public float Elasticity; public float ElasticityFalloff; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs deleted file mode 100644 index 46c5618b3..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs +++ /dev/null @@ -1,255 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using System.Collections.Generic; -using System.Linq; -using Unity.Collections; -using Unity.Entities; -using Unity.Mathematics; - -namespace VisualPinball.Unity -{ - internal struct QuadTree - { - private BlobArray> _children; - private BlobArray> _bounds; - private float3 _center; - private bool _isLeaf; - - public static void Create(BlobBuilder builder, ref BlobArray> colliders, ref QuadTree dest, Aabb rootBounds) - { - var children = builder.Allocate(ref dest._children, 4); - var aabbs = new List(); - var cs = new List(); - for (var i = 0; i < colliders.Length; i++) { - if (colliders[i].Value.Type != ColliderType.Plane) { - var c = colliders[i].Value; - var bounds = colliders[i].Value.Bounds(); - //Debug.Log("Adding aabb " + aabb + " (" + colliders[i].Value.Type + ")"); - if (bounds.ItemId == 0) { - throw new InvalidOperationException($"Entity of {bounds} must be set ({colliders[i].Value.ItemType})."); - } - if (bounds.ColliderId < 0) { - throw new InvalidOperationException($"ColliderId of {bounds} must be set ({colliders[i].Value.ItemType})."); - } - - aabbs.Add(bounds); - cs.Add(c); - } - } - - dest.CreateNextLevel(builder, rootBounds, 0, 0, aabbs, ref children); - } - - private void CreateNextLevel(BlobBuilder builder, Aabb bounds, int level, int levelEmpty, - IReadOnlyCollection remainingBounds, ref BlobBuilderArray> children) - { - _center.x = (bounds.Left + bounds.Right) * 0.5f; - _center.y = (bounds.Top + bounds.Bottom) * 0.5f; - _center.z = (bounds.ZLow + bounds.ZHigh) * 0.5f; - - if (remainingBounds.Count <= 4) { - CopyBounds(builder, remainingBounds.ToArray(), ref _bounds); - _isLeaf = true; - return; - } - - _isLeaf = false; - - ref var child0 = ref builder.Allocate(ref children[0]); - ref var child1 = ref builder.Allocate(ref children[1]); - ref var child2 = ref builder.Allocate(ref children[2]); - ref var child3 = ref builder.Allocate(ref children[3]); - - var childBounds0 = new List(); - var childBounds1 = new List(); - var childBounds2 = new List(); - var childBounds3 = new List(); - - var vRemain = new List(); // hit objects which did not go to a quadrant - - //_unique = HitObjects[0].E ? HitObjects[0].Item as Primitive : null; - - // sort items into appropriate child nodes - foreach (var b in remainingBounds) { - int oct; - - // if ((hitObject.E ? hitObject.Item : null) != _unique) { - // // are all objects in current node unique/belong to the same primitive? - // _unique = null; - // } - - if (b.Aabb.Right < _center.x) { - oct = 0; - - } else if (b.Aabb.Left > _center.x) { - oct = 1; - - } else { - oct = 128; - } - - if (b.Aabb.Bottom < _center.y) { - oct |= 0; - - } else if (b.Aabb.Top > _center.y) { - oct |= 2; - - } else { - oct |= 128; - } - - if ((oct & 128) == 0) { - switch (oct) { - case 0: childBounds0.Add(b); break; - case 1: childBounds1.Add(b); break; - case 2: childBounds2.Add(b); break; - case 3: childBounds3.Add(b); break; - } - - } else { - vRemain.Add(b); - } - } - - // copy remaining AABBs to blob - CopyBounds(builder, vRemain, ref _bounds); - - // check if at least two nodes feature objects, otherwise don't bother subdividing further - var countEmpty = vRemain.Count == 0 ? 1 : 0; - if (childBounds0.Count == 0) ++countEmpty; - if (childBounds1.Count == 0) ++countEmpty; - if (childBounds2.Count == 0) ++countEmpty; - if (childBounds3.Count == 0) ++countEmpty; - - if (countEmpty >= 4) { - ++levelEmpty; - - } else { - levelEmpty = 0; - } - - if (_center.x - bounds.Left > 0.0001 //!! magic - && levelEmpty <= 8 // If 8 levels were all just subdividing the same objects without luck, exit & Free the nodes again (but at least empty space was cut off) - && level + 1 < 128 / 3) - { - CreateNextLevel(builder, ref child0, ref childBounds0, GetBounds(0, in _center, in bounds), level, levelEmpty); - CreateNextLevel(builder, ref child1, ref childBounds1, GetBounds(1, in _center, in bounds), level, levelEmpty); - CreateNextLevel(builder, ref child2, ref childBounds2, GetBounds(2, in _center, in bounds), level, levelEmpty); - CreateNextLevel(builder, ref child3, ref childBounds3, GetBounds(3, in _center, in bounds), level, levelEmpty); - - } else { - child0._isLeaf = true; - child1._isLeaf = true; - child2._isLeaf = true; - child3._isLeaf = true; - } - } - - private static void CreateNextLevel(BlobBuilder builder, ref QuadTree child, ref List childBounds, - in Aabb bounds, int level, int levelEmpty) - { - var children = builder.Allocate(ref child._children, 4); - child.CreateNextLevel(builder, bounds, level + 1, levelEmpty, childBounds, ref children); - - } - - private static void CopyBounds(BlobBuilder builder, IReadOnlyList src, ref BlobArray> dest) - { - var boundsBlob = builder.Allocate(ref dest, src.Count); - for (var i = 0; i < src.Count; i++) { - ref var bounds = ref builder.Allocate(ref boundsBlob[i]); - bounds.Aabb = src[i].Aabb; - bounds.ItemId = src[i].ItemId; - bounds.ColliderId = src[i].ColliderId; - } - } - - private static Aabb GetBounds(int i, in float3 center, in Aabb bounds) - { - return new Aabb { - Left = (i & 1) != 0 ? center.x : bounds.Left, - Top = (i & 2) != 0 ? center.y : bounds.Top, - ZLow = bounds.ZLow, - Right = (i & 1) != 0 ? bounds.Right : center.x, - Bottom = (i & 2) != 0 ? bounds.Bottom : center.y, - ZHigh = bounds.ZHigh - }; - } - - public void GetAabbOverlaps(in BallState ball, in NativeHashMap itemsColliding, ref DynamicBuffer matchedColliderIds) - { - var ballAabb = ball.Aabb; - var collisionRadiusSqr = ball.CollisionRadiusSqr; - - for (var i = 0; i < _bounds.Length; i++) { - ref var bounds = ref _bounds[i].Value; - // if (itemsColliding[bounds.ColliderEntity] && bounds.Aabb.IntersectRect(ballAabb) && bounds.Aabb.IntersectSphere(ball.Position, collisionRadiusSqr)) { - // matchedColliderIds.Add(new OverlappingStaticColliderBufferElement { Value = bounds.ColliderId }); - // } - } - - if (!_isLeaf) { - var isLeft = ballAabb.Left <= _center.x; - var isRight = ballAabb.Right >= _center.x; - - if (ballAabb.Top <= _center.y) { - // Top - if (isLeft) { - _children[0].Value.GetAabbOverlaps(in ball, in itemsColliding, ref matchedColliderIds); - } - - if (isRight) { - _children[1].Value.GetAabbOverlaps(in ball, in itemsColliding, ref matchedColliderIds); - } - } - - if (ballAabb.Bottom >= _center.y) { - // Bottom - if (isLeft) { - _children[2].Value.GetAabbOverlaps(in ball, in itemsColliding, ref matchedColliderIds); - } - - if (isRight) { - _children[3].Value.GetAabbOverlaps(in ball, in itemsColliding, ref matchedColliderIds); - } - } - } - } - - public override string ToString() - { - var bounds = new ColliderBounds[_bounds.Length]; - for (var i = 0; i < _bounds.Length; i++) { - bounds[i] = _bounds[i].Value; - } - return $"[({bounds.Length}){string.Join(" - ", bounds)}]"; - } - - public string ToString(int level) - { - var ident = new string(' ', level * 3); - var str = ident + ToString() + "\n"; - if (!_isLeaf) { - for (var i = 0; i < _children.Length; i++) { - str += _children[i].Value.ToString(level + 1); - } - } - return str; - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs.meta deleted file mode 100644 index 473ad6d34..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTree.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2579132f809b4cb4c9dd7cc096e0b430 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeBlob.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeBlob.cs deleted file mode 100644 index 8f6523132..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeBlob.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -namespace VisualPinball.Unity -{ - internal struct QuadTreeBlob - { - public QuadTree QuadTree; - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeBlob.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeBlob.cs.meta deleted file mode 100644 index 68201732c..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeBlob.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a51d8de4406f6ab42bfb26abb969b085 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs deleted file mode 100644 index fbac9ab37..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System.Collections.Generic; -using System.Linq; -using NLog; -using Unity.Collections; -using Unity.Entities; -using Unity.Jobs; -using Unity.Profiling; -using UnityEngine; -using Logger = NLog.Logger; - -namespace VisualPinball.Unity -{ - internal static class QuadTreeCreator - { - private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - private static readonly ProfilerMarker PerfMarkerTotal = new ProfilerMarker("QuadTreeCreator"); - private static readonly ProfilerMarker PerfMarkerGenerateColliders = new ProfilerMarker("QuadTreeCreator (1 - generate colliders)"); - private static readonly ProfilerMarker PerfMarkerCreateColliders = new ProfilerMarker("IColliderGenerator.CreateColliders"); - private static readonly ProfilerMarker PerfMarkerCreateBlobAsset = new ProfilerMarker("QuadTreeCreator (2 - allocate blob asset)"); - private static readonly ProfilerMarker PerfMarkerCreateQuadTree = new ProfilerMarker("QuadTreeCreator (3 - create quad tree)"); - private static readonly ProfilerMarker PerfMarkerSaveToEntity = new ProfilerMarker("QuadTreeCreator (4 - save to entity)"); - - public static void Create(EntityManager entityManager, out NativeHashMap itemsColliding) - { - PerfMarkerTotal.Begin(); - - // var player = Object.FindObjectOfType(); - // var playfieldComponent = player.GetComponentInChildren(); - // var itemApis = player.ColliderGenerators.ToArray(); - // - // // 1. generate colliders - // PerfMarkerGenerateColliders.Begin(); - // var colliderList = new List(); - // //var (playfieldCollider, glassCollider) = player.PlayfieldApi.CreateColliders(0); - // itemsColliding = new NativeHashMap(itemApis.Length, Allocator.Persistent); - itemsColliding = new NativeHashMap(0, Allocator.Persistent); - // foreach (var itemApi in itemApis) { - // // fixme job - // // PerfMarkerCreateColliders.Begin(); - // // if (itemApi.ColliderEntity != Entity.Null) { - // // itemsColliding.Add(itemApi.ColliderEntity, itemApi.IsColliderEnabled); - // // } - // // itemApi.CreateColliders(colliderList, 0); - // // PerfMarkerCreateColliders.End(); - // } - // PerfMarkerGenerateColliders.End(); - // - // // 2. allocate created colliders - // PerfMarkerCreateBlobAsset.Begin(); - // var allocateColliderJob = new ColliderAllocationJob(colliderList/*, playfieldCollider, glassCollider*/); - // allocateColliderJob.Run(); - // - // // retrieve result and dispose - // var colliderBlobAssetRef = allocateColliderJob.BlobAsset[0]; - // allocateColliderJob.Dispose(); - // PerfMarkerCreateBlobAsset.End(); - // - // // 3. Create quadtree blob (BlobAssetReference) from AABBs - // PerfMarkerCreateQuadTree.Begin(); - // BlobAssetReference quadTreeBlobAssetRef; - // using (var builder = new BlobBuilder(Allocator.Temp)) { - // ref var rootQuadTree = ref builder.ConstructRoot(); - // QuadTree.Create(builder, ref colliderBlobAssetRef.Value.Colliders, ref rootQuadTree.QuadTree, - // playfieldComponent.BoundingBox.ToAabb()); - // - // quadTreeBlobAssetRef = builder.CreateBlobAssetReference(Allocator.Persistent); - // } - // PerfMarkerCreateQuadTree.End(); - // - // // save it to entity - // PerfMarkerSaveToEntity.Begin(); - // //Debug.Log(quadTreeBlobAssetRef.Value.QuadTree.ToString(0)); - // var collEntity = entityManager.CreateEntity(ComponentType.ReadOnly(), ComponentType.ReadOnly()); - // entityManager.SetComponentData(collEntity, new QuadTreeData { Value = quadTreeBlobAssetRef }); - // entityManager.SetComponentData(collEntity, new ColliderData { Value = colliderBlobAssetRef }); - // PerfMarkerSaveToEntity.End(); - // - // Logger.Info("Static QuadTree initialized."); - - PerfMarkerTotal.End(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs.meta deleted file mode 100644 index 98de850db..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeCreator.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0c7f237e205800f41842b62b2105c45c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeData.cs deleted file mode 100644 index 1d8326a1c..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeData.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinball.Unity -{ - internal struct QuadTreeData : IComponentData - { - public BlobAssetReference Value; - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeData.cs.meta deleted file mode 100644 index 94bc9db5e..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/QuadTreeData.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d0fc1537caa35b945967fa9073314ff6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs index e00fc834c..47e2c5b71 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Event/EventData.cs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using VisualPinball.Engine.Game; namespace VisualPinball.Unity diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallApi.cs deleted file mode 100644 index 941748482..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallApi.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinball.Unity -{ - public class BallApi - { - private readonly Entity Entity; - private readonly Player Player; - - protected readonly EntityManager EntityManager = World.DefaultGameObjectInjectionWorld.EntityManager; - - public BallApi(Entity entity, Player player) - { - Entity = entity; - Player = player; - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallApi.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallApi.cs.meta deleted file mode 100644 index ab0463d92..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallApi.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 451d480ce82baf34d899d5205034ed7c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs index 3a4810081..bf50db4f2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallDisplacementPhysics.cs @@ -16,9 +16,8 @@ using Unity.Mathematics; using UnityEngine; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class BallDisplacementPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs deleted file mode 100644 index 8bdf41e50..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinball.Unity -{ - /// - /// List of triggers and kickers the ball is now inside - /// - /// It's what VPX calls `m_vpVolObjs` - [InternalBufferCapacity(0)] - internal struct BallInsideOfBufferElement : IBufferElementData - { - public int Value; - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs.meta deleted file mode 100644 index 718ce9c27..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallInsideOfBufferElement.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 54b4dcc117bbc004897a4adadc89fddb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs index f309490b1..205962853 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallMovementPhysics.cs @@ -14,12 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Profiling; using UnityEngine; -using VisualPinball.Unity; -using Physics = VisualPinball.Unity.Physics; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class BallMovementPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs index c3a490e29..7075970e8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallSpinHackPhysics.cs @@ -14,16 +14,13 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; -using VisualPinball.Unity; // ReSharper disable CompareOfFloatsByEqualityOperator -namespace VisualPinballUnity +namespace VisualPinball.Unity { - [DisableAutoCreation] internal static class BallSpinHackPhysics { internal static void Update(ref BallState ball) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallState.cs index 95fcfdc5e..efef6c68b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallState.cs @@ -14,14 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; -using VisualPinballUnity; namespace VisualPinball.Unity { - // todo split this into at least 2 components - internal struct BallState : IComponentData + internal struct BallState { public int Id; public float3 Position; @@ -79,19 +76,6 @@ public Aabb Aabb { } } - public BallColliderBounds Bounds(Entity entity) - { - var vl = math.length(Velocity) + Radius + 0.05f; // 0.05f = paranoia - return new BallColliderBounds(entity, new Aabb( - Position.x - vl, - Position.x + vl, - Position.y - vl, - Position.y + vl, - Position.z - vl, - Position.z + vl - )); - } - public float CollisionRadiusSqr { get { var v1 = math.length(Velocity) + Radius + 0.05f; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs index 6beae0b93..287f9e134 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallVelocityPhysics.cs @@ -18,9 +18,8 @@ using Unity.Mathematics; using VisualPinball.Engine.Common; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class BallVelocityPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/EventArgs.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/EventArgs.cs index 00f65a2f1..41c14ea55 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/EventArgs.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/EventArgs.cs @@ -14,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs index 72aa99a30..27c95e65a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperApi.cs @@ -18,11 +18,8 @@ #pragma warning disable 67 using System; -using System.Collections.Generic; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; -using VisualPinball.Engine.Common; using VisualPinball.Engine.VPT.Flipper; namespace VisualPinball.Unity diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs index 4573a5445..1f0f1b06a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs @@ -16,8 +16,6 @@ // ReSharper disable InconsistentNaming -using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Flipper; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index d021e59a8..0716c8069 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -506,7 +506,7 @@ internal FlipperState CreateState() GetVelocityData(d), GetHitData(), GetFlipperTricksData(colliderComponent, d), - new SolenoidStateData { Value = false } + new SolenoidState { Value = false } ); // flipper correction (nFozzy) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs index cd3f306bf..74db32a91 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Mathematics; using Unity.Entities; +using Unity.Mathematics; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs index 43e531e8d..723096bed 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs @@ -18,7 +18,7 @@ namespace VisualPinball.Unity { - public struct FlipperCorrectionState : IComponentData + public struct FlipperCorrectionState { public bool IsEnabled; public BlobAssetReference Value; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs index d3277dc82..83d5ad1bc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperDisplacementPhysics.cs @@ -17,9 +17,8 @@ using Unity.Collections; using Unity.Mathematics; using VisualPinball.Engine.Game; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class FlipperDisplacementPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperHitData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperHitData.cs index 8182069d9..a14d485c1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperHitData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperHitData.cs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; namespace VisualPinball.Unity { - internal struct FlipperHitData : IComponentData + internal struct FlipperHitData { public bool LastHitFace; public float2 HitVelocity; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementState.cs index db61e0709..79fe66e12 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperMovementState.cs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; namespace VisualPinball.Unity { - internal struct FlipperMovementState : IComponentData + internal struct FlipperMovementState { public float Angle; public float AngleSpeed; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs index 087867841..eab2654d0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperState.cs @@ -24,11 +24,11 @@ internal struct FlipperState internal FlipperVelocityData Velocity; internal FlipperHitData Hit; internal FlipperTricksData Tricks; - internal SolenoidStateData Solenoid; + internal SolenoidState Solenoid; public FlipperState(int itemId, FlipperStaticData @static, FlipperMovementState movement, FlipperVelocityData velocity, FlipperHitData hit, FlipperTricksData tricks, - SolenoidStateData solenoid) + SolenoidState solenoid) { ItemId = itemId; Static = @static; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperStaticData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperStaticData.cs index 95d61f84b..478bb1290 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperStaticData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperStaticData.cs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; namespace VisualPinball.Unity { - internal struct FlipperStaticData : IComponentData + internal struct FlipperStaticData { public float3 Position; public float Inertia; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperTricksData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperTricksData.cs index 65196a82b..69cb1285b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperTricksData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperTricksData.cs @@ -14,12 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; -using Unity.Mathematics; - namespace VisualPinball.Unity { - internal struct FlipperTricksData : IComponentData + internal struct FlipperTricksData { // used in flippertricks // internals diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityData.cs index 058ec9253..2c646d23f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityData.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct FlipperVelocityData : IComponentData + internal struct FlipperVelocityData { public bool Direction; public float CurrentTorque; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs index e4ba38d41..08cb16ab7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperVelocityPhysics.cs @@ -18,9 +18,8 @@ using Unity.Mathematics; using VisualPinball.Engine.Common; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class FlipperVelocityPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/SolenoidStateData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/SolenoidState.cs similarity index 88% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/SolenoidStateData.cs rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/SolenoidState.cs index 8b4a92cb6..bfdebed5d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/SolenoidStateData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/SolenoidState.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct SolenoidStateData : IComponentData + internal struct SolenoidState { public bool Value; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/SolenoidStateData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/SolenoidState.cs.meta similarity index 100% rename from VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/SolenoidStateData.cs.meta rename to VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/SolenoidState.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs index f1053382d..a4f28e686 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateApi.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using System; -using System.Collections.Generic; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.VPT.Gate; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs index bb5c210d0..7e1e85ef3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs @@ -16,9 +16,7 @@ // ReSharper disable InconsistentNaming -using System; using System.ComponentModel; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Gate; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs index 4ce758ef7..ca417bfd8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateDisplacementPhysics.cs @@ -17,9 +17,8 @@ using Unity.Collections; using Unity.Mathematics; using VisualPinball.Engine.Game; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class GateDisplacementPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs index 2d71b8821..5765b77f0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateVelocityPhysics.cs @@ -18,9 +18,8 @@ using Unity.Mathematics; using VisualPinball.Engine.Common; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class GateVelocityPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs index 9beebb371..5e95675c7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetAnimation.cs @@ -15,9 +15,8 @@ // along with this program. If not, see . using VisualPinball.Engine.Game; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class DropTargetAnimation { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimation.cs index 621028cb4..b3a9029b6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimation.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetAnimation.cs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using VisualPinball.Unity; - -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class HitTargetAnimation { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs index 1615d987f..a773e3104 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs @@ -16,8 +16,6 @@ // ReSharper disable InconsistentNaming -using System; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.HitTarget; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs index db467a1e8..6a4a9e5db 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using System; -using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.Game.Engines; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs index 288edd319..4a9e0c905 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs @@ -15,11 +15,9 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; using VisualPinball.Engine.Game; -using VisualPinball.Unity.Collections; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs index c02f036c2..19cee1cf3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs @@ -16,8 +16,6 @@ // ReSharper disable InconsistentNaming -using System; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Kicker; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionState.cs index 2f0980a8d..db6398b7d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollisionState.cs @@ -14,11 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - internal struct KickerCollisionState : IComponentData + internal struct KickerCollisionState { public int BallId; public int LastCapturedBallId; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticState.cs index 9a95ae63f..445d28bae 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerStaticState.cs @@ -14,12 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; namespace VisualPinball.Unity { - internal struct KickerStaticState : IComponentData + internal struct KickerStaticState { public bool LegacyMode; public bool FallThrough; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs index 435bbe97b..61731e108 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs @@ -16,8 +16,6 @@ // ReSharper disable InconsistentNaming -using System; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.MetalWireGuide; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs index b727e9612..b1904bbca 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs @@ -19,7 +19,6 @@ using System; using System.Collections.Generic; using NativeTrees; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Common; @@ -29,7 +28,6 @@ using VisualPinball.Engine.VPT.Primitive; using VisualPinball.Engine.VPT.Table; using VisualPinball.Unity.Playfield; -using VisualPinballUnity; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs index 1ff277717..ce31f7f61 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerAnimation.cs @@ -15,9 +15,8 @@ // along with this program. If not, see . using Unity.Mathematics; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class PlungerAnimation { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs index 55dd49b21..553049073 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs @@ -16,8 +16,6 @@ // ReSharper disable InconsistentNaming -using System; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Plunger; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs index 24360d318..8bd332457 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerDisplacementPhysics.cs @@ -17,9 +17,8 @@ using Unity.Collections; using Unity.Mathematics; using VisualPinball.Engine.Game; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class PlungerDisplacementPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs index 08a2ced25..daf53c805 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerVelocityPhysics.cs @@ -15,9 +15,8 @@ // along with this program. If not, see . using VisualPinball.Engine.VPT.Plunger; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class PlungerVelocityPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs index 217d3e97e..a7ce42205 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs @@ -16,8 +16,6 @@ // ReSharper disable InconsistentNaming -using System; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Ramp; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs index b69957394..4ae3a9362 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs @@ -16,8 +16,6 @@ // ReSharper disable InconsistentNaming -using System; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Rubber; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs index 5e6849fc7..ccc5f7940 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerApi.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using System; -using System.Collections.Generic; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Spinner; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs index 5b6ad81a5..4ee2a06da 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs @@ -16,8 +16,6 @@ // ReSharper disable InconsistentNaming -using System; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Spinner; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs index 77c36ca1b..12d5c480c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerDisplacementPhysics.cs @@ -19,9 +19,8 @@ using Unity.Collections; using Unity.Mathematics; using VisualPinball.Engine.Game; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class SpinnerDisplacementPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs index e6911492f..6bff32dd1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerVelocityPhysics.cs @@ -16,9 +16,8 @@ using Unity.Mathematics; using VisualPinball.Engine.Common; -using VisualPinball.Unity; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class SpinnerVelocityPhysics { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs index cb6035f99..369a74778 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs @@ -16,8 +16,6 @@ // ReSharper disable InconsistentNaming -using System; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.VPT.Surface; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs index 43a3464f2..288927336 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterApi.cs @@ -17,12 +17,10 @@ // ReSharper disable ConvertIfStatementToSwitchStatement using System; -using Logger = NLog.Logger; using NLog; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; -using VisualPinballUnity; +using Logger = NLog.Logger; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs index 39afe21a5..58b749c3e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs @@ -17,7 +17,6 @@ // ReSharper disable InconsistentNaming using System; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.VPT.Trigger; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs index 76af397dc..62f22ee02 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerTransform.cs @@ -16,10 +16,8 @@ using System.Collections.Generic; using UnityEngine; -using VisualPinball.Unity; -using Physics = VisualPinball.Unity.Physics; -namespace VisualPinballUnity +namespace VisualPinball.Unity { internal static class TriggerTransform { From ba47b7a02386ccfd139aafe7729dcb88cd342feb Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 16 Oct 2023 22:02:42 +0200 Subject: [PATCH 114/159] jobs: Fix flipper correction. --- .../VPT/Flipper/FlipperComponent.cs | 73 +++++++++---------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index 0716c8069..e95bb38a2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -663,55 +663,45 @@ private void SetupFlipperCorrection(FlipperColliderComponent colliderComponent) triggerComponent.DragPoints = new DragPointData[poly.Count]; triggerComponent.IsLocked = true; triggerCollider.HitHeight = 150F; // nFozzy's recommendation, but I think 50 should be ok - var flipperRotation = Matrix4x4.Rotate(quaternion.Euler(new float3(0, 0, -_startAngle))); + + // this was taken from the 2021 code when we had the playfield transformed to vpx world: + // p = ta.transform.InverseTransformPoint(transform.TransformPoint(poly[i])) + // this is basically (ta.transform.worldToLocalMatrix * transform.localToWorldMatrix) + // but I couldn't get this transformation correctly from our current transforms. + // using Matrix4x4.Rotate(quaternion.Euler(new float3(0, 0, -_startAngle))) and transforming + // to localPos was close, but not close enough. + var flipperToPlayfield = new Matrix4x4( + new Vector4(-0.50754f, 0.86163f, 0, 0), + new Vector4(-0.86163f, -0.50754f, 0, 0), + new Vector4(0, 0, 1f, 0), + new Vector4(278.21380f, 1803.27200f, 0, 1f) + ); for (var i = 0; i < poly.Count; i++) { // Poly points are expressed in flipper's frame: rotate to get it to the correct position. - var p = flipperRotation.MultiplyPoint(poly[i]); - triggerComponent.DragPoints[poly.Count - i - 1] = new DragPointData(localPos.x - p.x, localPos.y - p.y); + var p = flipperToPlayfield.MultiplyPoint3x4(poly[i]); + triggerComponent.DragPoints[poly.Count - i - 1] = new DragPointData(p.x, p.y); } // create polarities and velocities curves var polarities = new float2[fc.PolaritiesCurveSlicingCount + 1]; - if (fc.Polarities != null) - { - var curve = fc.Polarities; - float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.PolaritiesCurveSlicingCount; - int i = 0; - for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) - { - polarities[i].x = t; - polarities[i++].y = curve.Evaluate(t); - } - } - else - { - for (int i = 0; i < fc.PolaritiesCurveSlicingCount + 1; i++) - { - polarities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; - polarities[i].y = 0F; + if (fc.Polarities != null) { + Discretize(fc.Polarities, polarities); + + } else { + for (var i = 0; i < fc.PolaritiesCurveSlicingCount + 1; i++) { + polarities[i++] = new float2(i / (float)fc.PolaritiesCurveSlicingCount, 0); } } triggerCollider.FlipperPolarities = polarities; var velocities = new float2[fc.VelocitiesCurveSlicingCount + 1]; - if (fc.Velocities != null) - { - var curve = fc.Velocities; - float stepP = (curve[curve.length - 1].time - curve[0].time) / fc.VelocitiesCurveSlicingCount; - int i = 0; - for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) - { - velocities[i].x = t; - velocities[i++].y = curve.Evaluate(t); - } - } - else - { - for (int i = 0; i < fc.VelocitiesCurveSlicingCount + 1; i++) - { - velocities[i].x = i / (float)fc.PolaritiesCurveSlicingCount; - velocities[i].y = 1F; + if (fc.Velocities != null) { + Discretize(fc.Velocities, velocities); + + } else { + for (var i = 0; i < fc.VelocitiesCurveSlicingCount + 1; i++) { + velocities[i++] = new float2(i / (float)fc.PolaritiesCurveSlicingCount, 1f); } } triggerCollider.FlipperVelocities = velocities; @@ -721,6 +711,15 @@ private void SetupFlipperCorrection(FlipperColliderComponent colliderComponent) GetComponentInParent().RegisterTrigger(triggerComponent); } + private static void Discretize(AnimationCurve curve, IList outArray) + { + var stepP = (curve[curve.length - 1].time - curve[0].time) / (outArray.Count - 1); + var i = 0; + for (var t = curve[0].time; t <= curve[curve.length - 1].time; t += stepP) { + outArray[i++] = new float2(t, curve.Evaluate(t)); + } + } + #endregion } } From 36f5579aef311bdb6905ab44ba07ab327fb605c4 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 17 Oct 2023 22:49:13 +0200 Subject: [PATCH 115/159] editor: Add icon for ball component. --- .../Assets/Editor/Icons/small_blue/ball.png | Bin 0 -> 1184 bytes .../Editor/Icons/small_blue/ball.png.meta | 127 ++++++++++++++++++ .../Assets/Editor/Icons/small_gray/ball.png | Bin 0 -> 1182 bytes .../Editor/Icons/small_gray/ball.png.meta | 127 ++++++++++++++++++ .../Assets/Editor/Icons/small_green/ball.png | Bin 0 -> 1184 bytes .../Editor/Icons/small_green/ball.png.meta | 127 ++++++++++++++++++ .../Assets/Editor/Icons/small_orange/ball.png | Bin 0 -> 1182 bytes .../Editor/Icons/small_orange/ball.png.meta | 127 ++++++++++++++++++ .../VPT/Ball/BallComponent.cs.meta | 14 +- 9 files changed, 519 insertions(+), 3 deletions(-) create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_blue/ball.png create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_blue/ball.png.meta create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_gray/ball.png create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_gray/ball.png.meta create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_green/ball.png create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_green/ball.png.meta create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_orange/ball.png create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_orange/ball.png.meta diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_blue/ball.png b/VisualPinball.Unity/Assets/Editor/Icons/small_blue/ball.png new file mode 100644 index 0000000000000000000000000000000000000000..7442a5ea5d44ecd609f476171f7ec00fbc74a725 GIT binary patch literal 1184 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+9I14-?iy0W${Xm$pP}SUmfq^B+ z)5S3)qBZHy|Nr)f7qIj2@BmdZ{QsXMCA2OjApy!+*rv#P{lBDvfdK~)TP*O5O-M+n zxUk?P%c7GAJxbQEq}ToT21;=>SoO_s_|y+Hj$J}R!ptPYNLS&e5gQxGIY85uZY~6x zX9_e+MBt%C48xNboV>Gq6pA~T;SNx`1ya)J#3v&4sbWej&@De2j%+`^_?sd#v$IpP zny|)_kIV=IPk~hX00?>Co*|;dH0D1$ zmtjDZ^LGwQhV99c5)u$254{Y~xyb8P&j&P2et{xKk;1ko4x9((@c=^rs^V2Z#<83I zhbJ!B!tOQwhmol20YT+vLztTmg&HePFJ170?Wx}cWyiqcd2M|z+ohQh+6y$c%yB96 zVAgPVmbIMU#@E7Fxk6f?p|Oz>9IA)J7M;j^0(AOimW-0ihbP{+a{vS&b~_bnm|U6A zJ&i5n7~@jUDyF&>(F$;#PW*uZmK{6}d@lZ6Uzj+y!-L7GT%+hUd&uhsr^&Zm1vWA~ z6oUtOleNe!zKM%vLtG|YDOg~{;A(%u7Z`i61mwgQ81O=oIpC{DuT;AbL!mG;Gc(wg zPGuTZi^b>K3otwangvY|hpvk{o{wM#B^HQt4?Pbkl0J3?5dl(CbFJaZfo25i=2|g# z%!X?K3KfYbZD2qa%6tZjt4R_%nV*w^5xS%z36`Rr{1-QC{u0bfgbS2w?3I@P!Ei_y z?t?=a5BVp(aPKTba%PxK<1a5}-hjLCa6NQ2o$2c5FB!KQcUdaz{xb21LvLxodof11 z!w!W$c>Fdwn6tsn%R#p?#XV{JY!121*Gql*-sMK9!f0kl-^gFv#iP;E#0JlnOUp>E=S9 zd6_`7G!zaM?qE1^QCR7av%@n1c7$QKKuQ=}Wi(8leAL)|0%#v&XMVr?TW2=5ww8_$ z0s$V65zbXQ1yVf|X!V4C*H;P}R*o0D=I|}d6l)P(;K@9{S>3Iry&;Li9B3odtuHQ! zYF}?~GL-YJP}caRe8^eO;cA1Ckj7r2*=ZLK9s*e~>o_0WIfq^c==8BHUC$6vvNmET zn@G}vEp6`vix~2b8yOftj6C!*K<6T_S3RHLLq+)oiX24>+nzXZ9+=02FyvK0#<83I zhbJ!B!tOQwhmol20YT+vL%0E<#){KR7rbD5>Ni2zF|c@ETc68zX(ojB0*x(mT*^F{ zHQb$LE$6rKwJ=t$kQQiYY-9ww;Q#+aVv9~>K1p<`IKh%pa{2JY8+U-=ao_;Nbxxj( zBb;;vXURFHs^~73miA}~-wuxtC;q?y%MKogJ{NzkFH9WUfpG@aRjyI=nmy!oLziNf zxZ@F~mT0(Znyf`;@lDJY2@rG)I^1}wLH?B*8wfx(@&yLGP-G7H>d`CJF2qnM%*@OT zl==VPsZ674vG`nj0ft8i)rYQ&I-ZYUM#TQ1=K)31$F3kESW0THHNx;RjX>R8E9Q>b zaMu8hEfP=KzLaW8AYf9@+e%riNqj1_K81o{w~dl!{V=n-J3 z6uM&A((Ai$xx0XZjmI%qN?7!5gR*ABk3@I4Z>6M|cf$2bNjX1;a~7TY!aMII+l0q< r0X8?`{+5#Z>;qRKB^4_OH;I{H!7+|czpTv8fRcfytDnm{r-UW|!#xcG#2(H(lxGLZEr3 zK(j;y9$LgOJbA%c=X2WOnE*&N)UaD1C5=veB2u3!ro;l>@}uF%_T!7cDKaxVH_2Z% z3h;Q0aIVrRkZNC`)hCWCl?sT=U6A4G*M7l-`w-WKC5`6~3jduktucwi9H;NIpQb609tVL$=O!Ob5BbX7Uc+fI>y$NgEiDg)*Ok;%btFPUh#uz!c;0@yLM#5XU?DFK*WSC7728OAkPg z?v+OrKFr6!#Rsi zec_#Vl5N6cy8xS;a9>MFefEJXk&=oPgqy_7u+N3vNJ7GIHYlV$UHx3vIVCg!0N}Ey AlmGw# literal 0 HcmV?d00001 diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_green/ball.png.meta b/VisualPinball.Unity/Assets/Editor/Icons/small_green/ball.png.meta new file mode 100644 index 000000000..033351cf5 --- /dev/null +++ b/VisualPinball.Unity/Assets/Editor/Icons/small_green/ball.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 5d0b9cba9947e3d4ab5bcb515913d088 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_orange/ball.png b/VisualPinball.Unity/Assets/Editor/Icons/small_orange/ball.png new file mode 100644 index 0000000000000000000000000000000000000000..dd0d086d8ed6817f6c65b2397ba04fa04f9c081b GIT binary patch literal 1182 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+9I14-?iy0W${Xm$pP}SUmfq^B! z)5S3)qBZHy|Nr)f7qIj2@BmdZ{QsXMCA2OjApy!+*ru2t{gy{ULV^W|WiBkyGcYi) z5m;x(vgjm2kCOGP``d1*0;O0SWRLqh{B&nyYhwl)Dc!P~UsvI#5gQxGIY85uZY~6x zCj~T%tD`_hkD=%b%fnaB3dJ2D)len3KuR1G*|~TtZBFSK85qn`Gd|wSKA#7Tcm*spvJ$r zuzhXWf`A@(;d>libwJzs7i2j|a!!fs^xga-VPU~n#eiAI`G78js6X^NK&Ovo>3W8U zlD)ZGnOh|^)-J4Wk!iTS5$@tcF9UQg@_Nn+;)ZIuvTGIK6bi3$~|z6OzHeF;zu(v9z>DOZaxU)1CMO11vju9Qs`RxxO%QY=^tpsa&JzHG9bGhAzb{amOP} zEzxk-G+B$x;+vQ)5+LXpbhzNvxz<=&5Im|OTrHmDBO$0_KH1jMfnb0G^P$_i9 zu%*{`;c|BY1sjiJFjp`7wn165;YT7ccS5tHloaz$xLzqK=f`l)qElaZ=bdDm@YpWE q<|f?VQc|CN;7X*VVg=zQF*DrC<@hwm^D+l0ggjmST-G@yGywqiwVycv literal 0 HcmV?d00001 diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_orange/ball.png.meta b/VisualPinball.Unity/Assets/Editor/Icons/small_orange/ball.png.meta new file mode 100644 index 000000000..faeb91a5c --- /dev/null +++ b/VisualPinball.Unity/Assets/Editor/Icons/small_orange/ball.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 7e22e740622cf2243bfe316adbf63442 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 2 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs.meta index 1b96be544..dd724599c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs.meta +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs.meta @@ -1,3 +1,11 @@ -fileFormatVersion: 2 -guid: a04fca20ce2246b9abf456441b587efd -timeCreated: 1678725159 \ No newline at end of file +fileFormatVersion: 2 +guid: a04fca20ce2246b9abf456441b587efd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {fileID: 2800000, guid: 7e22e740622cf2243bfe316adbf63442, type: 3} + userData: + assetBundleName: + assetBundleVariant: From c6672d88dd392fddd11fb2274cd12a693b4fdd32 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 17 Oct 2023 23:27:13 +0200 Subject: [PATCH 116/159] editor: Add icon for physics engine. --- .../Editor/Icons/small_blue/physics.png | Bin 0 -> 1163 bytes .../Editor/Icons/small_blue/physics.png.meta | 127 ++++++++++++++++++ .../Editor/Icons/small_gray/physics.png | Bin 0 -> 1166 bytes .../Editor/Icons/small_gray/physics.png.meta | 127 ++++++++++++++++++ .../Editor/Icons/small_green/physics.png | Bin 0 -> 1166 bytes .../Editor/Icons/small_green/physics.png.meta | 127 ++++++++++++++++++ .../Editor/Icons/small_orange/physics.png | Bin 0 -> 1166 bytes .../Icons/small_orange/physics.png.meta | 127 ++++++++++++++++++ .../Game/PhysicsEngine.cs.meta | 12 +- 9 files changed, 518 insertions(+), 2 deletions(-) create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_blue/physics.png create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_blue/physics.png.meta create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_gray/physics.png create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_gray/physics.png.meta create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_green/physics.png create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_green/physics.png.meta create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_orange/physics.png create mode 100644 VisualPinball.Unity/Assets/Editor/Icons/small_orange/physics.png.meta diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_blue/physics.png b/VisualPinball.Unity/Assets/Editor/Icons/small_blue/physics.png new file mode 100644 index 0000000000000000000000000000000000000000..36628c047ab24d38f5f3ed1d2b0094a4ce497947 GIT binary patch literal 1163 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+9I14-?iy0W${Xm$pP}SUmfq})= z)5S3)qBZHy|Nr)f6WDmK|Ccl{FpvN$XZZg=snK%N!(aA{25V1#Nn9YyR~o~_%?UO-HmhA`v9jb#F+Y*0 z!2arS$cY06f?zwCmS1dp{ojG_wEHB3oC_&Tt?wMHK!!*$LY%;qeJw>RAt7N0$J9y> zZg!>JQyUu>%6BW<8yOhn99h-e*a%SwbOx8hz8H>EiCegQH5~lH6plB(;Q^VLnpV(u zjDd%T2jX6-36D5uUEwpyFlsb1@Zk};^wr}OAJDKH&5=Ajy%05rUIt`DF-cBwcr3tn z^XY*D2R6uit`PKcmN|Fe0SDM!PJLA+y+A82U1W=p^j3CnI@8v!qoE>gGSgvUH^Q<* zuL9WE+SomE0%mS&aC^tXI6?X6!kmCvty3Q_IMBqv#s-QXU`QX5TQti@p}nb#U!tHv zjdc}M#;%s7&H@|KQ0U2&?k7{1!u2TKUU=b?fXOLGod}Pz&{GEvKs>u> zP1>atCey1Og*qoDs+hhG0A@f)bS<(lc9eb4q5QY;h{IMv*S-{Z05SFUPr9>Ifk9=# zC;b&^O3a5@A!ad|e)d?q{v|)$8&XoNb}-|lr1(-{AxsRLnZaqt+lB5$GfY8-d%F6$ JtaD0e0szo7sipt` literal 0 HcmV?d00001 diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_blue/physics.png.meta b/VisualPinball.Unity/Assets/Editor/Icons/small_blue/physics.png.meta new file mode 100644 index 000000000..6df27d4e6 --- /dev/null +++ b/VisualPinball.Unity/Assets/Editor/Icons/small_blue/physics.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 9fa698499ac650c43ad57ac3d6a6b63b +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 2 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_gray/physics.png b/VisualPinball.Unity/Assets/Editor/Icons/small_gray/physics.png new file mode 100644 index 0000000000000000000000000000000000000000..833e5181ad74c1e0f0c8ed6f78f144ca50ae4aa0 GIT binary patch literal 1166 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+9I14-?iy0W${Xm$pP}SUmfq})r z)5S3)qBZHy|Nr)f6WFxF))^)wBp3jdGyMOb)M#0B^pq)+f|ZiZlfw?yGOu>9u(7o< zu(7dK0_kRmDkf_Yt&NS1jSrbZiVQ6H7$qbmpxR^hC2eJ5W%#5$lmxE%JyaGXlq!sV;s;1{NFyzvcB z4+lSEYFa_tF$SO!5QS0`9&ygP!spV`-e6?l!y|I(tH&umBLjmQ&5=Ajy%05rUIt`D zF-cBwcr3tn^C{5A4f38V1ihSP&K-Eb0aWt;zf)gTNiWcfOBdN9B)yg0o6fYg>u9Jb zA98kB*p0C4(5nDoP_cXD1kBvl;P#G%af0&Cg*gGUTBklmlQcz64purJqlGMx=7)8Q;n5iRF0*CtiLIPZ`_HQ%MF3C!w|+T zAz=qmCAA`k-)p);|KUY4Q}hBCRRN<=!M)kpTFItG5bX3Ob1#n#3?jBumPN+A6q0Os z)6inT%*+gyQ?hbd*vmE{Ex^;EteU~Q(sReIw1fnR!G~tLZDg3RKJjXty-DxHR~}zV zI6oOYG@8}e$OzGUYvF}WydlvC7>aJX_b4Zda`5D+ScSn8gp#U@BZJ7Q1tzW9u@6}; z1TlwAXqK`&aa6tz7{CxKlq|11Uw*}0RLvCdSD{@vUf0+Fni!?N)T$W((cYWn}~0eWu0}AA1O#XkVquZvZn_ z$=YS(7R64+z7$nvcx)_EaXH!P^=Z+3nASx{7QT>d532&&0E>)88oiU4PrTBFo3v=R z^GPOnDg*IWT|}rpve1H^d&Qb|U`~Ms7tqWnQ@Wo_T?*HubbH~2PXZ>V9Cac*%0f@U z0tIN38!)lX$~s~p_QYe-tWpiQmljzVJIX%jQ2yI^#9^zTYhMaHgqV8!C*4`9z@W0= zlm3b{CFaAdkdR|C{p_)J{Y!qh%cP`O?O?GlCB>Ht3u0o}%nX5CZ#_5XF+2hp?&<31 Jvd$@?2>?t4rF#GX literal 0 HcmV?d00001 diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_gray/physics.png.meta b/VisualPinball.Unity/Assets/Editor/Icons/small_gray/physics.png.meta new file mode 100644 index 000000000..399973a30 --- /dev/null +++ b/VisualPinball.Unity/Assets/Editor/Icons/small_gray/physics.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 3b3e5e84308143f41ab28ab8be7765a5 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 2 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_green/physics.png b/VisualPinball.Unity/Assets/Editor/Icons/small_green/physics.png new file mode 100644 index 0000000000000000000000000000000000000000..6c491079afb8c469ff5688975344c5122ebed9f7 GIT binary patch literal 1166 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+9I14-?iy0W${Xm$pP}SUmfq})r z)5S3)qBZHy|Nr)f6WC_|bConOFpvN$XZZg=snN3N@_r3Qfw#xEygBS(E%Ryz3maP- z0~;G#C6I20sA94f(c0M9*!Yksq{zU6k5NJbrv1(j^B|Cf-K30#@|QPpmK4dH$eVE3 zf$z%kl@l5hmB5xTEx+jde~|;kaJ{Jb7LbT#2{-CE{AnQj{yCah1q8fS0PJMoprmlDoT1`my9 z!D2w^*1`*$ctfHOFcjT%?@>+^<>1Ltu?mAH2qje)M+T8q3rt$IV;{0y2x1PK&@5$l z;;4KbFn}ReC|O>2zWj>0sG2F@uR^a}&FC4S1Y=FDZ)Og}!4}lZyt5o@csT^vfwadmWik*yo zDXPry*jS|Eat&5Hzopr E0LWLczyJUM literal 0 HcmV?d00001 diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_green/physics.png.meta b/VisualPinball.Unity/Assets/Editor/Icons/small_green/physics.png.meta new file mode 100644 index 000000000..30eeeda64 --- /dev/null +++ b/VisualPinball.Unity/Assets/Editor/Icons/small_green/physics.png.meta @@ -0,0 +1,127 @@ +fileFormatVersion: 2 +guid: 795073756b9fd6745bdb8a4dad302cc7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 12 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 2 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 0 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 2 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 64 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 0 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Server + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/VisualPinball.Unity/Assets/Editor/Icons/small_orange/physics.png b/VisualPinball.Unity/Assets/Editor/Icons/small_orange/physics.png new file mode 100644 index 0000000000000000000000000000000000000000..084b1f4906055eafa6497caf0dbead43a24638f5 GIT binary patch literal 1166 zcmeAS@N?(olHy`uVBq!ia0vp^S|H591|*LjJ{b+9I14-?iy0W${Xm$pP}SUmfq})r z)5S3)qBZHy|Nr)f6WH>j-||RENbmraGyMOb)M)uBclBI`4zYE1UlJF{@|DIgF*7?e zFf%vXFf$)^gs5V&7SY<+*x2}xDWu52f{ziXAF93Pa?V!x3ayFfkDoZRn3i!5S2i8a5?OY;W(AJh09mN!7ohVc;g!$k#%+~ zr_Ma!=|#9pYQiJVSy%WtfR?2u%#hGn@_OPF*_4EY4eXoY)*gBpkP*csImO|z0Nc%{ zKu>It_go?9A?dB`-gKs|T}MNubv1vZlQ_b%L$3nZ z*xJ}Vasp;bw&RAVI=m1F53>u<{78+T&n@<3qNGOiIbFsOm3l3EeN z?=@Ya|L`K2DSCm6e&w!~J#q2D1z;o|fjGU%+{u0)cWSFo%@oJpCN$=Avq*fWHdu!tuJsFuzNEsZ}#bfH_5JWyK-Z1v6Q$Ec@yn%$ybP zcOZCzFgx6)MHVg_zwm8n?7VQyva$j0K2zg~k39rVw69X-H-MR|WbLwXi()5ZUy3R- zJT?}oxSZ_t`m|_1OzWZ}3tvdKhgAV>fFbXis|bBU>1Z#*CGpJN7)A*%6}V=IBXSk?E@xbXk;<<_D{OARDnTd!6*F{X-dq8 zSs@|JWct}-?fRGeaF Date: Tue, 17 Oct 2023 23:48:37 +0200 Subject: [PATCH 117/159] editor: Add new icons to manager. --- .../VisualPinball.Unity.Editor/Utils/Icons.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/Icons.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/Icons.cs index d47362d73..1a9abde26 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/Icons.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Utils/Icons.cs @@ -62,6 +62,7 @@ public IconVariant(string name, IconSize size, IconColor color) } private const string AssetLibraryName = "asset_library"; + private const string BallName = "ball"; private const string BallRollerName = "ball_roller"; private const string BoltName = "bolt"; private const string BumperName = "bumper"; @@ -85,6 +86,7 @@ public IconVariant(string name, IconSize size, IconColor color) private const string PlugName = "plug"; private const string PlungerName = "plunger"; private const string PrimitiveName = "primitive"; + private const string PhysicsName = "physics"; private const string RampName = "ramp"; private const string RotatorName = "rotator"; private const string RubberName = "rubber"; @@ -114,9 +116,9 @@ public IconVariant(string name, IconSize size, IconColor color) private const string DisplayEventName = "display_event"; private static readonly string[] Names = { - AssetLibraryName, BallRollerName, BoltName, BumperName, CalendarName, CannonName, CoilName, DropTargetBankName, DropTargetName, FlasherName, + AssetLibraryName, BallRollerName, BallName, BoltName, BumperName, CalendarName, CannonName, CoilName, DropTargetBankName, DropTargetName, FlasherName, FlipperName, GateName, GateLifterName, HitTargetName, KeyName, KickerName, LightGroupName, LightName, MechName, MechPinMameName, PlayfieldName, PlugName, - PlungerName, PrimitiveName, RampName, RotatorName, RubberName, ScoreReelName, ScoreReelSingleName, SlingshotName, SpinnerName, SurfaceName, + PhysicsName, PlungerName, PrimitiveName, RampName, RotatorName, RubberName, ScoreReelName, ScoreReelSingleName, SlingshotName, SpinnerName, SurfaceName, SwitchNcName, SwitchNoName, TableName, TeleporterName, TriggerName, TroughName, CoilEventName, SwitchEventName, LampEventName, LampSeqName, MetalWireGuideName, PlayerVariableName, PlayerVariableEventName, TableVariableName, TableVariableEventName, UpdateDisplayName, DisplayEventName @@ -163,6 +165,7 @@ private static IIconLookup[] GetLookups() { } public static Texture2D AssetLibrary(IconSize size = IconSize.Large, IconColor color = IconColor.Gray) => Instance.GetItem(AssetLibraryName, size, color); + public static Texture2D Ball(IconSize size = IconSize.Small, IconColor color = IconColor.Gray) => Instance.GetItem(BallName, size, color); public static Texture2D BallRoller(IconSize size = IconSize.Large, IconColor color = IconColor.Gray) => Instance.GetItem(BallRollerName, size, color); public static Texture2D Bolt(IconSize size = IconSize.Large, IconColor color = IconColor.Gray) => Instance.GetItem(BoltName, size, color); public static Texture2D Bumper(IconSize size = IconSize.Large, IconColor color = IconColor.Gray) => Instance.GetItem(BumperName, size, color); @@ -183,6 +186,7 @@ private static IIconLookup[] GetLookups() { public static Texture2D Mech(IconSize size = IconSize.Large, IconColor color = IconColor.Gray) => Instance.GetItem(MechName, size, color); public static Texture2D MechPinMame(IconSize size = IconSize.Large, IconColor color = IconColor.Gray) => Instance.GetItem(MechPinMameName, size, color); public static Texture2D MetalWireGuide(IconSize size = IconSize.Large, IconColor color = IconColor.Gray) => Instance.GetItem(MetalWireGuideName, size, color); + public static Texture2D Physics(IconSize size = IconSize.Small, IconColor color = IconColor.Gray) => Instance.GetItem(PhysicsName, size, color); public static Texture2D Playfield(IconSize size = IconSize.Large, IconColor color = IconColor.Gray) => Instance.GetItem(PlayfieldName, size, color); public static Texture2D Plug(IconSize size = IconSize.Large, IconColor color = IconColor.Gray) => Instance.GetItem(PlugName, size, color); public static Texture2D Plunger(IconSize size = IconSize.Large, IconColor color = IconColor.Gray) => Instance.GetItem(PlungerName, size, color); @@ -273,6 +277,7 @@ internal class IconLookup : IIconLookup public Texture2D Lookup(T mb, IconSize size = IconSize.Large, IconColor color = IconColor.Gray) where T : class { switch (mb) { + case BallComponent _: return Icons.Ball(size, color); case BallRollerComponent _: return Icons.BallRoller(size, color); case BumperComponent _: return Icons.Bumper(size, color); case CannonRotatorComponent _: return Icons.Cannon(size, color); @@ -285,6 +290,7 @@ public Texture2D Lookup(T mb, IconSize size = IconSize.Large, IconColor color case KickerComponent _: return Icons.Kicker(size, color); case LightComponent _: return Icons.Light(size, color); case LightGroupComponent _: return Icons.LightGroup(size, color); + case PhysicsEngine _: return Icons.Physics(size, color); case PlungerComponent _: return Icons.Plunger(size, color); case PlayfieldComponent _: return Icons.Playfield(size, color); case PrimitiveComponent _: return Icons.Primitive(size, color); @@ -309,6 +315,7 @@ public Texture2D Lookup(T mb, IconSize size = IconSize.Large, IconColor color public void DisableGizmoIcons() { + Icons.DisableGizmo(); Icons.DisableGizmo(); Icons.DisableGizmo(); Icons.DisableGizmo(); @@ -337,6 +344,7 @@ public void DisableGizmoIcons() Icons.DisableGizmo(); Icons.DisableGizmo(); Icons.DisableGizmo(); + Icons.DisableGizmo(); Icons.DisableGizmo(); Icons.DisableGizmo(); Icons.DisableGizmo(); From 6a4450e59e79225a2bfd8863b48919845869378b Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 17 Oct 2023 23:57:49 +0200 Subject: [PATCH 118/159] editor: Add physics inspector and make components work on playfield instead of root node. --- .../Inspectors/PhysicsEngineInspector.cs | 43 ++++++++++++++++++ .../Inspectors/PhysicsEngineInspector.cs.meta | 3 ++ .../Inspectors/PlayerInspector.cs | 44 ++----------------- .../Game/BallRollerComponent.cs | 2 +- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 13 +++++- .../VisualPinball.Unity/Game/PhysicsEnv.cs | 4 +- .../VisualPinball.Unity/Game/Player.cs | 3 +- .../VPT/Playfield/PlayfieldComponent.cs | 26 ++++++----- 8 files changed, 78 insertions(+), 60 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PhysicsEngineInspector.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PhysicsEngineInspector.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PhysicsEngineInspector.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PhysicsEngineInspector.cs new file mode 100644 index 000000000..e6ed34144 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PhysicsEngineInspector.cs @@ -0,0 +1,43 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using UnityEditor; +using UnityEngine; + +namespace VisualPinball.Unity.Editor +{ + [CustomEditor(typeof(PhysicsEngine))] + public class PhysicsEngineInspector : UnityEditor.Editor + { + private SerializedProperty _gravityProperty; + + private void OnEnable() + { + _gravityProperty = serializedObject.FindProperty(nameof(PhysicsEngine.GravityStrength)); + } + + public override void OnInspectorGUI() + { + EditorGUI.BeginChangeCheck(); + + EditorGUILayout.PropertyField(_gravityProperty, new GUIContent("Gravity Constant")); + + if (EditorGUI.EndChangeCheck()) { + serializedObject.ApplyModifiedProperties(); + } + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PhysicsEngineInspector.cs.meta b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PhysicsEngineInspector.cs.meta new file mode 100644 index 000000000..d5cec9090 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PhysicsEngineInspector.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c082aa8d96384de191a3ac3700f3b06b +timeCreated: 1697578139 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs index ee10bdc85..9c3db3957 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/PlayerInspector.cs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System.Linq; +// ReSharper disable AssignmentInConditionalExpression + using UnityEditor; using UnityEngine; -using VisualPinball.Engine.Common; namespace VisualPinball.Unity.Editor { @@ -25,21 +25,13 @@ namespace VisualPinball.Unity.Editor [CanEditMultipleObjects] public class PlayerInspector : UnityEditor.Editor { - private string[] _physicsEngineNames; - private int _physicsEngineIndex; - - private string[] _debugUINames; - private int _debugUIIndex; - private bool _toggleDebug = true; private SerializedProperty _updateDuringGameplayProperty; private void OnEnable() { - var player = (Player)target; - - _updateDuringGameplayProperty = serializedObject.FindProperty(nameof(player.UpdateDuringGamplay)); + _updateDuringGameplayProperty = serializedObject.FindProperty(nameof(Player.UpdateDuringGamplay)); } public override void OnInspectorGUI() @@ -67,35 +59,5 @@ public override void OnInspectorGUI() EditorGUILayout.EndFoldoutHeaderGroup(); } - - private void DrawEngineSelector(string engineName, ref string engineId, ref T[] instances, ref string[] names, ref int index) where T : IEngine - { - if (instances == null) { - // get all instances - instances = EngineProvider.GetAll().ToArray(); - names = instances.Select(x => x.Name).ToArray(); - - // set the current index based on the table's ID - index = -1; - for (var i = 0; i < instances.Length; i++) { - if (EngineProvider.GetId(instances[i]) == engineId) { - index = i; - break; - } - } - if (instances.Length > 0 && index < 0) { - index = 0; - engineId = EngineProvider.GetId(instances[index]); - } - } - if (names.Length == 0) { - return; - } - var newIndex = EditorGUILayout.Popup(engineName, index, names); - if (index != newIndex) { - index = newIndex; - engineId = EngineProvider.GetId(instances[newIndex]); - } - } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs index a48866eae..2b450be6a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/BallRollerComponent.cs @@ -43,7 +43,7 @@ private void Awake() var p2 = _ltw.MultiplyPoint(new Vector3(100f, 100f, z)); var p3 = _ltw.MultiplyPoint(new Vector3(100f, -100f, z)); _playfieldPlane.Set3Points(p1, p2, p3); - _physicsEngine = GetComponentInParent(); + _physicsEngine = GetComponentInChildren(); } private void Update() diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 8d14e5672..d5dfb53c0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -13,6 +13,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +// ReSharper disable InconsistentNaming + using System; using System.Collections.Generic; using System.Diagnostics; @@ -30,6 +32,13 @@ namespace VisualPinball.Unity { public class PhysicsEngine : MonoBehaviour { + #region Configuration + + [Tooltip("Gravity constant, in VPX units.")] + public float GravityStrength = 1.762985f; + + #endregion + #region States [NonSerialized] private AABB _playfieldBounds; @@ -151,9 +160,9 @@ internal void DisableCollider(int itemId) private void Awake() { - _player = GetComponent(); + _player = GetComponentInParent(); _insideOfs = new InsideOfs(Allocator.Persistent); - _physicsEnv[0] = new PhysicsEnv(NowUsec, GetComponent()); + _physicsEnv[0] = new PhysicsEnv(NowUsec, GetComponentInChildren(), GravityStrength); } private void Start() diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs index e0bcc3519..0d6d446bb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEnv.cs @@ -31,13 +31,13 @@ public struct PhysicsEnv : IDisposable public Random Random; - public PhysicsEnv(ulong startTimeUsec, Player player) : this() + public PhysicsEnv(ulong startTimeUsec, PlayfieldComponent playfield, float gravityStrength) : this() { StartTimeUsec = startTimeUsec; CurPhysicsFrameTime = StartTimeUsec; NextPhysicsFrameTime = StartTimeUsec + PhysicsConstants.PhysicsStepTime; Random = new Random((uint)UnityEngine.Random.Range(1, 100000)); - Gravity = player.Gravity; + Gravity = playfield.PlayfieldGravity(gravityStrength); } public void Dispose() diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index cf00e96a9..e8548627a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -102,7 +102,7 @@ private PlayfieldComponent PlayfieldComponent { private PhysicsEngine PhysicsEngine { get { if (_physicsEngine == null) { - _physicsEngine = GetComponent(); + _physicsEngine = GetComponentInChildren(); } return _physicsEngine; } @@ -120,7 +120,6 @@ private PhysicsEngine PhysicsEngine { public Dictionary CoilStatuses => _coilPlayer.CoilStatuses; public Dictionary LampStatuses => _lampPlayer.LampStates; public Dictionary WireStatuses => _wirePlayer.WireStatuses; - public float3 Gravity => PlayfieldComponent.Gravity; public int NextBallId => ++_currentBallId; private int _currentBallId; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs index b1904bbca..1035f641b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs @@ -68,8 +68,6 @@ public class PlayfieldComponent : MainRenderableComponent public int PlayfieldDetailLevel = 10; - public float GravityStrength = 1.762985f; - [SerializeField] private string _playfieldImage; [SerializeField] private string _playfieldMaterial; @@ -94,14 +92,11 @@ public class PlayfieldComponent : MainRenderableComponent public Aabb Bounds => new Aabb(Left, Right, Top, Bottom, TableHeight, GlassHeight); public AABB2D Bounds2D => new AABB2D(new float2(Left, Top), new float2(Right, Bottom)); - public float3 Gravity { - get { - var tableComponent = GetComponentInParent(); - var difficulty = tableComponent ? tableComponent.GlobalDifficulty : 0.2f; - var slope = AngleTiltMin + (AngleTiltMax - AngleTiltMin) * difficulty; - var strength = tableComponent.OverridePhysics != 0 ? PhysicsConstants.DefaultTableGravity : GravityStrength; - return new float3(0, math.sin(math.radians(slope)) * strength, -math.cos(math.radians(slope)) * strength); - } + public float3 PlayfieldGravity(float strength) { + var tableComponent = GetComponentInParent(); + var difficulty = tableComponent ? tableComponent.GlobalDifficulty : 0.2f; + var slope = AngleTiltMin + (AngleTiltMax - AngleTiltMin) * difficulty; + return new float3(0, math.sin(math.radians(slope)) * strength, -math.cos(math.radians(slope)) * strength); } private void Awake() @@ -118,6 +113,7 @@ private void Awake() public override IEnumerable SetData(TableData data) { + var physicsEngine = GetComponentInParent(); var updatedComponents = new List { this }; // position @@ -131,7 +127,9 @@ public override IEnumerable SetData(TableData data) Bottom = data.Bottom; AngleTiltMax = data.AngleTiltMax; AngleTiltMin = data.AngleTiltMin; - GravityStrength = data.Gravity; + if (physicsEngine) { + physicsEngine.GravityStrength = data.Gravity; + } // playfield material _playfieldImage = data.Image; @@ -190,6 +188,8 @@ public IEnumerable SetReferencedData(PrimitiveData primitiveData, public override TableData CopyDataTo(TableData data, string[] materialNames, string[] textureNames, bool forExport) { + var physicsEngine = GetComponentInParent(); + // position data.TableHeight = TableHeight; data.GlassHeight = GlassHeight; @@ -199,7 +199,9 @@ public override TableData CopyDataTo(TableData data, string[] materialNames, str data.Bottom = Bottom; data.AngleTiltMax = AngleTiltMax; data.AngleTiltMin = AngleTiltMin; - data.Gravity = GravityStrength; + if (physicsEngine) { + data.Gravity = physicsEngine.GravityStrength; + } // playfield material data.Image = _playfieldImage; From ca0d44a890529fdf9eea05568ec73675dd25c775 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 18 Oct 2023 00:02:26 +0200 Subject: [PATCH 119/159] import: Add physics engine to hierarchy. --- .../Import/VpxSceneConverter.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs index 17899b0fc..b72bd03ed 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs @@ -573,13 +573,8 @@ private void CreateRootHierarchy(string tableName = null) .Replace("%TABLENAME%", _sourceTable.Name) .Replace("%INFONAME%", _sourceContainer.InfoName); } - - // 1. create table scene - // _tableScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Additive); - // _tableScene.name = tableName; - // SceneManager.SetActiveScene(_tableScene); - // 2. create game object hierarchy + // 1. create game object hierarchy _tableGo = new GameObject(tableName); _playfieldGo = new GameObject("Playfield"); var backglassGo = new GameObject("Backglass"); @@ -592,7 +587,8 @@ private void CreateRootHierarchy(string tableName = null) backglassGo.transform.SetParent(_tableGo.transform, false); cabinetGo.transform.SetParent(_tableGo.transform, false); - // 3. add components + // 2. add components + _playfieldGo.AddComponent(); _playfieldComponent = _playfieldGo.AddComponent(); _playfieldGo.AddComponent(); _playfieldGo.AddComponent(); From 35e9259d887b27cbddc1fd440548bb7456af528e Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 19 Oct 2023 19:24:29 +0200 Subject: [PATCH 120/159] doc: Bump docfx to latest. --- .../Documentation~/android-chrome-192x192.png | Bin 6972 -> 0 bytes .../Documentation~/android-chrome-256x256.png | Bin 9699 -> 0 bytes .../Documentation~/api/.gitignore | 5 - .../Documentation~/api/index.md | 10 - .../Documentation~/apple-touch-icon.png | Bin 6599 -> 0 bytes VisualPinball.Unity/Documentation~/docfx.json | 164 ++++++-------- .../Documentation~/favicon-16x16.png | Bin 728 -> 0 bytes .../Documentation~/favicon-32x32.png | Bin 1231 -> 0 bytes .../Documentation~/favicon.ico | Bin 15086 -> 0 bytes .../Documentation~/favicon.png | Bin 13390 -> 15919 bytes .../Documentation~/filterConfig.yml | 10 - VisualPinball.Unity/Documentation~/index.md | 5 +- .../Documentation~/safari-pinned-tab.svg | 19 -- .../Documentation~/site.webmanifest | 12 - .../template/vpe/layout/_master.tmpl | 152 +++++++++++++ .../Documentation~/template/vpe/logo.svg | 10 +- .../template/vpe/partials/affix.tmpl.partial | 25 --- .../template/vpe/partials/head.tmpl.partial | 54 ----- .../template/vpe/partials/logo.tmpl.partial | 5 - .../template/vpe/partials/navbar.tmpl.partial | 20 -- .../template/vpe/{styles => public}/main.css | 15 +- .../template/vpe/styles/fonts.css | 208 ------------------ VisualPinball.Unity/Documentation~/toc.yml | 3 - VisualPinball.Unity/Documentation~/vpe.svg | 27 ++- 24 files changed, 261 insertions(+), 483 deletions(-) delete mode 100644 VisualPinball.Unity/Documentation~/android-chrome-192x192.png delete mode 100644 VisualPinball.Unity/Documentation~/android-chrome-256x256.png delete mode 100644 VisualPinball.Unity/Documentation~/api/.gitignore delete mode 100644 VisualPinball.Unity/Documentation~/api/index.md delete mode 100644 VisualPinball.Unity/Documentation~/apple-touch-icon.png delete mode 100644 VisualPinball.Unity/Documentation~/favicon-16x16.png delete mode 100644 VisualPinball.Unity/Documentation~/favicon-32x32.png delete mode 100644 VisualPinball.Unity/Documentation~/favicon.ico delete mode 100644 VisualPinball.Unity/Documentation~/filterConfig.yml delete mode 100644 VisualPinball.Unity/Documentation~/safari-pinned-tab.svg create mode 100644 VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl delete mode 100644 VisualPinball.Unity/Documentation~/template/vpe/partials/affix.tmpl.partial delete mode 100644 VisualPinball.Unity/Documentation~/template/vpe/partials/head.tmpl.partial delete mode 100644 VisualPinball.Unity/Documentation~/template/vpe/partials/logo.tmpl.partial delete mode 100644 VisualPinball.Unity/Documentation~/template/vpe/partials/navbar.tmpl.partial rename VisualPinball.Unity/Documentation~/template/vpe/{styles => public}/main.css (85%) delete mode 100644 VisualPinball.Unity/Documentation~/template/vpe/styles/fonts.css diff --git a/VisualPinball.Unity/Documentation~/android-chrome-192x192.png b/VisualPinball.Unity/Documentation~/android-chrome-192x192.png deleted file mode 100644 index ef4b5bf666f567645a7ee338be930e32e58f23b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6972 zcmaiZWmME()b4L!=s{XQYUqX;KuWrXkZzP3x^zI=0SBp}JEXe|8WE805ClO&kr*ZA zPe|9x`|;kj?z$iLe%9V+J^Oq(Yn}a^vttbO5agr}NC5yK*V0roy2I}OHDd6cKbtL! zzXPy~vaT`!)F+W$*%REwPzOyTT>uE?0RT({09@RqFq;722Lpg@I{=W)1^{|gUYnuZ z-2xs`2cZVsMkkGT-9;oQP0JSmKt}Vw1_E;O819lpzFNBKL^u)_QhK65>R22AFpg`f zDVqc?{>^tonS9R}dQ}Tjg|XWaiAoRp$EPL7IEYF1Kc;?^7@m;e<>|nimg6%!9$lS- zev?yE{eU+kr}_;=_2{>8lhl~|l1#lE^{%R9sdYd-X+4%DELjPUD*~LV)c);y550NX z_N$_^_H?iM<}`Zm^5SQ}FZm6Tje-|@pOTdc86E%suAhKZD7w0%S2ae&D&jf`dzN#h z9k_+M$%oGNfix)Kj2OnNM{x#yCAKD%R9C0Bu~)2#N35l;kj-*zR`vrzf>IUPkJs2? zFa3lVj<0V4)+!)FE-^~EhYzYkY1!Jjw|7_2cZ<&mF=G6!4?|Rh_bf&Cm8Yg0oLUQQ z6m>R#yThCN_7A&7Q}7g@G*#&H!e z)H5C#zZxa?t6U9u)Kzj`m$}cdSMBmbj;k0oqG%|nKUnqOjjg#bo03yn6$MYm%H(fY zA)XC!5|)Our6Cd4@h;hhibesRH^-9DUuv-|ynhK{`-!9#dq>j2XV^CkJR4!!MAjgm;Y8^#0m8|&g-AkgoDT|dUEH8^wyqRWDomU&11`= z2ODu(%p0%v7yesBfSBPw+>lBHW9{cOaqrwoM7@M&H+CRTyN66WPL!*n6~Bh``&JHR z28c$U5V7K(HteLENe{68&2qyNajZSodxRflsUCNpszUJ_!qsl(79L9aDGr(O#;RWc z?#VJN45E;OyeVx?h4cy_$Ab2|#| z;~buZ_gcqAbgv{PfZ5%CZ_3lh`*|-Ny_bS_y!_#ryALWPH2Bxe+m2j8JXZ$)1)T1TlY`d?LeD6)+B0rl`Vr&rP{@)}RW-E>f+>($z%?c(z@y zi&7rO>!%OVtOe0qy0ChKNjGHDcY`a0PJBict`qAM;~u-B@{&PxK+vZ9PB;EgRhj(4 zLtU+>m1-Wf6^tvepoqHDU=@YNG|!81ihonu50@RkOa5LdkH3HUZ;7`--Gy&eJ|gNb z=`W0ACwHeur%3Ar9&1Wxs*?Iu*BPHi;|N%KOg64T1E4*8Ik=;W%Vpj!rt6SbldRn@ zJE-Zk9u17zN;PjAzaM3Q&CgVnV+wC?dOc1op5L`D%Jp1P6J*UJNrGW=6sMKlaCDUZ z!lTf9lJ3B~K9m|yfeOz}^x{47|1m6VS^TaI&*05Qul+U()c{c#7~)A(4H?d(=DwvX zF#hyKQ0`gi8N+Fy;WUvmyf=tet|E!Lhc0N5hJ!`6TyrmPd@@K^4D6TINA4y2ux=mH zwW{ZOIL2eIm@{(hk@cD;K3ZotZGM>6W+S)a<@ESVA_L2AF_LrB8tGc{WM7N-eXu5ekni%N{^T<~1<30ybhksQRg1xB>y|Yb@5E@| zG;w5jr-Eo#e2JKIiSIJ)9M!It(hS$qVhgkZU826;Sc?@= zM~#qgms}6<{WBDJXreIrHuEIq@mjmi*6}4j8FzF0p7>qnokUU7VKz7u?9?OVoR#XRd3~WgH71{A9u8pzZH&6NGFLTXw zu^f8hJ-KE`L{ay;lG|jfDA|6-NDp9kN!w=$Kv;Z)V6-!TLUaE+EIO!B5uZgwhAjGx~@uxWYX1-9tmY&3l+3KdA1JOp*vPPeNR;>l?Y4+%U+eY zM)PR3EOZP(X7&MA*=j9Nc|n%DtS7FpN1HVh*P&LP_TLjax|Npe=mCttCfPHgDTI8a z-Y8=R&bpsESGvZiZy<0=LMX3tvBiS+Dw#VK%}G0DUl{smq+(M3yzegvg_Vm4sxhfr zFXLL0SpH3wD;*r2Z?+K!c1TtUr`9dZW?NUS(DGsZjq$or#|p2Z0t-0p#gyXX{CcN7 z=`Q#)9td=e>||O3wA4_ddY zi^CVYX}J9UCvqM%i0Ju|d<)~*hi&|hQ)?7R;sA-~FaGE0iSZ-31X* z)n$Z7Awdid^xwIIHV#E*>h9UnS8JuNw`)J7_Y{ekIZLk9@@X;h%s$3@C_6ld8ezL( z22i=4dv8d#R@=0AP=gdfJz}e2S=L77HfU6a*vz&X)ZkpFI=>G=@*Qt<1EAYW@j5Q^ z39n-`NKi6~qdqbX8&wd|Jp6(S=|p}_6lgNe0SDB=W68B8LN4+L5NP$(BZ+py`f4$4 zwPxb>Ys4JBT{80`p1KFkHjDr0?sFlW>8?PemEKTPjeSv=JRx^fV&Q&C)ApmyhD(Ky zDSdWas%~J&JUPhLc704RFS)HwvD@d*qC|4YZv3r?H_ZkAH?yw6ty7ZatQcy1 z%H6e&kP8+b^CqZuyq;PTcAr2grISkFOiZDsRbb>%^yyh@`7ytQF?U7@5?{3ZX?-gt zX+@*a_Kt6)5!xbs5-VTAXLJ}{Ozx*dVTmr3arSP?7Yp5Lnw`gFS&rW*5nSyXPEg-( z6?r878O2Ukgxd5{aLXY0aZz3?CAmTYg9sP3ag3-1>7^Q|OCn9Zu8>>k z-kSiz|6bTE4OXZYry)D{WL>{<-(=~4WCqo!wML`sTH{Dq|2R}19DpBM>CH5f%_C^_ zE)6|zK97D6`GKpv_<#&iVR6Q&Q>%n#*o@UE1J-hV#vevm9UuBF&U^V{ByRon?4J*y zyW3O0wkCPb%yE)WptXtGVx{raq=~?TyaZT}UlVYrqYGmm_gP*Wp5g~(uQx+g#bbBT_(O;va^t$`24u*R!58*C2qHdVnrHp*Y+%72)?vYiKD=1ehbS0GXZsw zud$<{L-gUZWVjpYe>w?CQv8nnH%-CyT2){FGR8I#5xepZwZ>8t%QYDYXSms{2aU!VyGj~W2^HY~ieS_|nSHJ(^YwWKHWl=e(m=1gIaXlyX(}!R zOOfp+Zqi~TV*k^06t7}@pILX8zvr<+<^wiSi)F1bTdg3+x3-)m`S|neNtii%KbcPx zdNck`yl7jR>v7UBQI)or35F%-PZ2uk+yBhV28Y;NUW|2K{Ke{~f39K#@DgLu>qb9r zV-aO-J=O1440V=_T6GMG%a`3wEYpKr#S(80R>jM|kr*j-$bCT=tvgsNmBG?$QYXJ| zF1<2ARwa7Kt(PXS9l0i-6~RX3?;n&W2eDNsPA!LX{ay2r+X;N7_|~^=Jj$b^MJ6-Alpsg*V`w^ZUMqIqk+dopog?uZ@YIJ!g)^#49pm2P5er8?&f) zMbRH+M!9F?N%3jxrwri+9$Th2LF<0Y@Yc_*;Y#+BN!rbdrg`!0mY!!dpWBpN9#LXTyE;ch}#BGI>R?i5Z zjYqm;-;j$sL*}CyXy2;6J;+fij;5|YnmrAiP1kYNm-qlj@K?|X?S{-p61^&8uxmH| z@z$(f8&Z&H$zQ(M-)a$^N>$>=TTYTCN4RP?R=Bmhingf4+_pygvDx?L?yz{$qD(kKEA8 zy590bS#(wUjO(-%=mrz@zMkvVyJ#qey6f|_W{tPMmV?)XeL2q<(`SiXKGpJ!{CH%3 z=x^<&VedEjpsfi5cXIA}5&pri7E6J_+3iB>%10<4wjK^G`=qbhaTDu@_w^0?*q63X z$F9P^MM@gQ*XIPwSu|DuM2|)`!bJrCtfC5E`xg)|avcl!!hbRQ^hWWI|H-~@&Eaax zgyW+Zy5KOd9G!G%iT}7pTqurg;{fIw@7scxquHsB*oTQq->o*R4uB$UVj*G);+=g= zR^9ZagAJ2^h~J83W!#-w*`|}Ae8p@n&^rELOCg<@@`x1`F8Rlge;$&Y8p=ZsrIZ<+4|5lu9eQPmmZbjg2?Y#N#JOv@LSCVrVNEQF1&1)u`*aq0P@`0y!?uqe?r1#6#{JXx zy#Wiv1q#OpeA463zc(q?_2%a17xl^lbG=V1XgN(fDP=skl4PyecMEk2Yg%zzWLZ#* z`4u}pOZ?{R1vK-Zmg?!bu^mw&)2Z-4OA>k40sL9<`ns<`pWh#4q8Ddj%?iWYxgI~X#2?1QrA+}eEwOA&6rGXjR^!#v*oEL2$kSce|P_seStXL_E-Y(vw8I^gXvtaf zf`8LJM$WlT#q3dMo&Ay5hHdyga^M$dh(Di10x-X3)L_swnW)+Yub+^Y99xJbAT{L2zI?!0e0Jrw1Bb`sV(C?O8r&KRTKr{ zxM!x;AG>UUKeT;yh%n7L_$r~~f8gCWy!DD%YAu8kGONcoSpAZq@m*}2^v_y4Tnn=~-0Z7h`rPjh&&fV19A*U)-Z_l7 zrTt02#(a&im*N!$Q)1zBmikGtywro3V1s%_0Xhx7^ufhg3af=bzJDB8&Z}bL{$zI> z=PU&wF`#8+%>sD355FUO>H~48=;&wv_9u#6s}>yLZai(vv*`;`+U5h6zt$oeO{CSE zL>dc=8Ev`JK|_?+9K4$kiuDIRF0dyw(>;Nt=vV$czN#3ex{e{|$=zfHjy=_yx7jFo z&d{CLdM*kzo@)L$o$(YqLS`b-orEauTNAnN#6ZDi@=cDyOaCVemUHX6MF5z~m-?hM z{F6MNkW)jDz@GDcQ7#oJY|{I5#$Ct*jdS648r_?Ss!|q%ZqoYkKxLQ){1tb?!k>6U zS?dXQyh!iF#y8&W7YqKHI>=;NLhK{Q`gvxT;Xc3EvkhV!*X(0jkG+UPlY&MzHo1wTlxBdISQlrRQN;4Iw`iT27CzBoA`+M}Db~K*?omSP? z!uoZTLm_E`R`0?t_v&VG$-fB$hAY{UBwz9^4xKIKG@OuuGKrI8)QlKV)GLsk<3ZOS zhMz>=@sbG0c*&?q?xv-gNTLYc0`t$HTJkGgDs?dqCoCCDeX(KRdhgBn?_m?)%MNO& z`3x6!uoF{$AEAnp{}EbP97jlH7zOu7O)M17$O{sVtOf^$DIjCY;6)(H^0q$%3?6UC zn`3Y}>o~zwXw>#54&FNQ)Mk#Pq%?oyX&%f!2G6A805H}qbXy$CK3wrTiG4C8`wiE8 z8*xSu*{gCUNgz~r0TEsexRCWyfp`y?>VqgY&K>OHN{h=h6xNVpBZWey5ugGMzxQYP z@cE|hKCPPbNUjZE8{eRf;cRH)B7gOz3xFhwh3c+z?dEUGYh)SJI__ICE60{!RMb zH!1JD5ZX-nzz)Lv?Oxrly~~v&wzf1Mqepl9+6tR}0LQ!WSJi zc~GHpsZT`+gl6m~`w1xMSke-))TF!Ho9l*nXyQ(qxL#cxbE-3-?iFFJcAye^^}?Z5 zFC`4^79f0-20CAN`3fF9;WDJN*Pu^=%#4Xugu}l~$*=sz&c&7DtT?<#Fzr`4FRE2; z(ziel+^?g&UwBT{5Kl6HklNHHSAC)krFGDTMlzsS;p6UKJ&zf;xfMNCxqonqQl5^& zh$I?wR=>I3@(%!jchuw+ncaHqN|i)w7)yI|V}mYDUDl+UXQ`e>LOQaWz+mC==hTPS{P*ubaXoVY1CT_OwDeKKxz??eu2T5j-om;jBDH zBNh%2Gm|lX|OJtX5!6hpc95g*sk@lL_QK|G*=??fO=YJv9vFT1qG~FbU9Pc!8u6Mo1>!b1gw-9wHG}TKt#@Qegqsd$x;oB5vjPN}K z_7}1-oWxcFd#s{seOM`huN3L=ZkoQkXR6j^!L9vcg!oA}6X&}%s|F9M2mBKlL1Mnc zosxv>ZXM8{>s@+&m=@weV`mYuTk<@Pqnr_d1`kvJocrnc9>;{cHav8F==!Ruy?vx) z$WK{IC04wMgtEDZrK5+xCH799ZC5p1Cpn`Z|2-)@gkS_=g92R!j`w^T4da?;$9RHw z5A|u@GV1spR)X+>^cU!7bC9rJs`o$5z56>4f}f&46zJ0ZDm2iYUJnQXYGnsl}2hDUqJvT@k8Nld$I&4qiXYf32pQt|;7Uuw0x^^CxgUH}r`+ zhlMw<)lQhdSA7iqoYCb1Wm$Y>1yKeju%Hx=r@)g^(FfBXhjr->E6MSJDu=jV#!}z| zWhWi?2WTP;t^?4Q#>4|(w_CSR`^Op+` zkhFL!=|4J&#P>8-_h_(v2q~k&U#YR}n%RKugA|`dMQ}9>O zixD^rxd}P@_ZhquBLN?lUgZybP2T-$y5PfK#h;7-nUb4Hn(sa1|9fWQhP}oA*M5~9 zhbr2-8})Ges$2Lv+WR`mI`}x<0U!nwg9*cAgvDe`;4oP+aaov@AWTda2FpRBqW=$q z*KXvH5Sq{p0=2{X}CJ%_40PV4I%G V_fX|w#@!Zxmb#wW2Nk>5{{v~T_51(; diff --git a/VisualPinball.Unity/Documentation~/android-chrome-256x256.png b/VisualPinball.Unity/Documentation~/android-chrome-256x256.png deleted file mode 100644 index c9da1dfda91ec3cc287ac75635dae5b15b8fa44b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9699 zcmbVyRa9I}uf?I+mxJz(%8$5#qmw}*z1q}|t36h{c1cEz*6C{w}Zi55{ zGQj0No`>^t9(q-GRaf`ws#>+b>fP}=+A0LNw738O5U8mt>Hz@SQx^@u20fAMV4IUC z0s_lv$pJt^3LeT9^J&avud1g706`o80F45GyC)WO9{}D90>GgS07zy702L(vyRP(; z0NqYQMG<(6O@Vhmjc_2Ural0GNA~|48jzb${lvubRnt3@>n~$2J zoI${^lY&5Zy5S#tG9no}8p$3Kex$=weyETkKlg6&Z|YZOV;PVec#{O@A zesepex&9Qcs{h;4((-T3mo>}vo(K#qLOOBC|EV*=-UejJqNPB<>&C5eY$36#7hPf6lUr^WyP$;Kb9Na{JfTZO<(KPuf^ZgV+DFTZ#;uScVnytpVPct|&K_nq zd-nPw|NcI+1|!LG{#~Co{avu^qcS=D-5aTEG_7IOJ2@+`*~M>%U!f}BK5deHLbwUP z89j^tUSnJfNqMG@2Ye4Cy=(il*cgqc8gdF=fv4D4F7P+0sYVKza8|5DjNk%WwWaC2 zJ(`z6yTNHvmuh41|3pM~&Kf0ZPQE@Xs0B+K=n*41+n&L<-tVT#Il#6Sf26hNFrKAv ztl9IHqyPFK)6XMIfW0s)H)Qi}cR1K`pasGCayb3#OGHhOF)7t`)I{$L%>cDV5PXl9eQ&_HUdYEK;#}p` z+rIZlM5gYM?e}nkFqFS5a&&FL!KD@wbE$PC|g; z?*>m#vALv|X{A?i%P?z|UpV(iuon$|!)#&XABeuil2+6%@`7~wNyU3z3wN+C7LkE4 z|2D@VqHi~W2g)Idb{t)!Z-g+{`xN+8O0KUEBK@_ypyOtX6f-ne6ZCT4U5wiVlyuL^ zYSw(p`;YjV--;9{(FH%k3DrwuWpZ&quEj+=s~@{7psaN8tN$cF+6Z82nK#87xAl78 z`KuRt^SHY01mD88HaU`B96~+{UFlCG2|lN0f5@DE5w5KSY?05F2bHD2MvB}I65=D~ zhPu{m)E(mab-9Li=%O+JS0Gt0QRU&gi)-VApY*s_j<+-yNR4QaF2Zt_lj6yRnoX$% zT#(dfAvq7OSaQg!5|uiorBUSyf9}Hf!&Nu*Rx)RaR>~gPJ$JwaP@9NF5}gr32?)B5R7F zF@n+}8saH`{QRvR^mEf1FAs52_&GVJ6@Y4x*SriC2yX1p3^1}|^a$W{ zwDsOE&DIcE6k@hL<>*soGDuV5d?4U2|bEN(8-6D#DzSvgWzH`H@ionV8 z>9wFemp^cLJ9PZ7i7N8tbxsIW(;gDBqY0NrT|e!jK(4X?Y>ita&g`2!n@t{fcM??v zSj;Tab#<7Fw_{J{zO6fHVR`q~rQhrZTAF4^EmWm2WC)yG*HL9FR1(9EDn$j!~O1n59JH%CC4}3U3wMv+Ym8q2quV^yq;HB5b{W->v zN=;BWo;3lTt8re?CmwjKr%$?^@DC{_0F*sH5^ItzrC0W7C{~ zfFs)D?0%dW71(9=8-810?68NgQ7un(?(KEV&j)E^nHx}o*k-Nt{4D);J{y`{UB_fZ>zAMQ_R1_T=Rxi;KN01Swwl|qlt4VQU=duZq9>GXZPzUuWJ@FE<>KD z*eT@!tw6J`>u)#o;JgIp+-6>kDMXeio5m6|lH;j?tBp?9X%WhYq(dh3OG zCxfPd4B#wQZX82@ zIqkcPXoG#My2T$?A~ajoU{i;Va2uF9ziO;C;9gE@9Ws;aMIuXo#u{X)v}ue|_51yn z2QOgRFZAY;xsoQ`iVPW$MASC8(8KZkyxS*N{jd+Owxv+&HUmr4RZ6zWtg2I4=*Ksi zdcUEkgmlhehxZeej=E#YlrHbx=z{ZzYK$rT+v#7Ww^k5|=@n#TTbZ>2M<`n=xX0Nc z2wIHhu!FbU!E~B7z+XXi=HD}nRL;MITHWUTuo%6&<-7Q7{!>JadSYMCCYv)qyzY^4 zb$+zPi!Hh1Nc6;|N%BXMF+HKFZn=(hQXA!jOV>7e+_HcO`3TrL0q*FaMpNsm@94(f&5Ydq*14&V~3|{)Yz+ts1b*Cz* zD$`3*j8+`&U3$9MmXOkD%2T?OfHK=SUau&UH0(>`?IUpA$Gdo($^U1L(krb$$`E$v z##^LKT-Fp-Q7DlH2sXG3^e_9wKPU5Mt{Y_`iu)w@?HD^6rKNI;{3O{5lhNLvD}KWe(}N%_v)Xlg-V)h{eJ$PImNHRs!?qVBkLVs$ zt9@x)L{%pHC52vw==1h%hf8&Hre-- zm1PKBwUog&de@Gkz1zB&&G%`~w5tcZ2^%QGh4rr395Er7J~Jlc3e9V9oTOi2WAdjj zv9*;0oHtB_bMr~*D%7|ie)s=F6)0P(^iNuo5*0HyWYmn#B(OyTv~u5)a5Y3eJo?N` zIYn2iB(EVN=g&!2Ej}yP)L+?VOjsD199wplIil#xGmc`&&$Hd?ifKrS&WB;!2!I&( zZ)!+LTxe5DV93~Ob*jYIInv87p7}MAwTG9kTRn_OCw*^idj4@mS-jtWlq@z)5lAA2 zt8y>mChOM?cHQT%nX0qgVn3^%=sR`@H4v#1eC+9v{;F#%u%laJ(Y9doY;ha@$W{*| zt$#M5OSL4!)^1Qzh{_x9kak*c*@3S_6wyFm|{*|!Az9tH@j9w@@a`W(^P5zeQF1T@8r>| zRj}IoUg` z9GY!b$4SF#b*(wgDM&xY1*U0q#w~Ii!1#Ehj9wxHybVv8@&e4>(`JJ3mbB6hSl4$Y zTcoQUO@#V}<@|(5FBv*|Szn0{#o3MW+n{wXI4?4>XGc!37Q*)AYn zPAU46_t>^xMx2Noo~`Rk9;p2JOMkrkL)^SQZ^t6;patALpd_~hb^Ngv_E44jPhpyk z<`1Nf(}c|NxjJ<`JwP4ZBpuUs{5@qcv5ev%+r{&uB<923YfXqj9}b8YqrbDbp->T0 zu;aT?0Y%5{d!&pCKgw*Q2-F67KG2^z`<@3HO}mYvsD{X`zws|$%G^o==3Y2PDgy>J z%C)h|N!YvQ0kOjrUJ9PcGju9`!g3g#h9uW7ew)*=hZSzVP9meMT&B~^WvzQJQ$sR( z6Q?SP)?>84!87DQztz|OlF#EofmcWzmg9D%KW=(*U0{c|r5fm-d8$>)W{|M1{bphI zfzgSFfx1OwPImOLSX^(*3!_stM1j z0@)PCu#0h+2XdX~LPx~s6$%b*^l)~cf=Z1SiXM?SH^2N1A6Z3kSI+@nHvYY_Ma4Tm z{VlLcw4ppJNXq1cYQZn5Q5X~JvZ;e_lvtzMt6LhG7RwdOwgY_dh{z)Q{tlH$ zj5(vd*sC&zj)?23x!3Tk6_d@aVHB0s^nT^*THN6WrMgcaHU&ybMZ_>bWwI3Rau|8H zBK7-keS9*5p8Q{PObC{1S@8QH%#cv+OJ7=esh1F1{G4I$%}*xPqK}{2+fo(-l}bN6 ztJ;JO5Yd9LU(VTBXCz`(b3k>w)?Z1#ctv=!Y51pskLM9ONVoIlDvUAMB_YSBG~Fp` z-riU+<#A+%_BP0F<7HjXyI$>IWu6Eie=os+aVl32-FeqTyywM(-HsSKqqv-efV0C` zK>VvEuGG!mL7+u?>Mi+OLLFD!hL;KDXKq7BoJ5OAt4&rC_q-xQI;O!`?{Ym{AVg3p zK8Hf|4zH-fs9)EekkNGZi^`$5Pxc9}ijZ77H>_{O=@v?d4QDQR;xjp0jw>fmlA=)Wc%9!mvbuSCf? z?7Uwu;k3z>K@XMrfX#DRoRbTSV19nR8WMS{o_7JG`nHZXZ*G z5up`3-683mBx%X%&=3w?1IOK8&dA3~UezSLYtgG=gEkY(;`K0h_490Dfb`vG)dlZ; z!iFs{83i?eFiS0KscS_xFDG8rFPPGg4p69z-(Z3w=wk5rw*osLAnglC-i zh(fOdzli2{;3DISxJ559=?J7?x7Fq2>tEeM`iAFtXGaz?H3PU4(v0yv+)6VJuJFU} zp6WJ{TG8)f)L0I=9&|HRhiGB%rdLg4TVJ-V_&z7qFdf~|rgSNHQ{^CR9CYXuZV88G zn$d`nD*nQ@k&;y!Az+fkm^O43r5jxB9OFTz;(em3c7Un9^s(A-z?^bpchlyGsa}Vv zqsT<{Q|osa^;`*>H>Fdwy^{vv=~!Xbd$t5TcPFdbmCQ`621L+=8tDNg^)lEM6nSG^ zsz5ax%DKi+`t{OCdhbxcqD-FkcxCVj?}{PU zxAsu{3geHWWL;N;;dlQ5vKHh@3v*KnAGRwEd2V)yZsEn_`l*@ciU&brJX#*C3f3L_wQeGIrYqfOh4a5;I>IBH6Rl*QRtJFr3RO2G2MuS zPBol2hI)ny@d^ITsP_|yX-)PILMi|0e@cW92;lZzozoX^`#+?zD1g>)zQy=Y%;=L~ zoO`t*z$;oE(L~Es3)odyy;JrfY0&F%tZ|r~``;t89qP{B?J)wEE zyn_=`L>T}!bGee=oQSd!9!7_*je}PmbI+VWjqhJq>6X&$arcYN$&wn!EmOdRb1-D= zLDSEsN1TpKS_8sJm8AT_M0vnVfUAOx5C}e`OJ&nV4%w!c^PT z^hDU{mcnUD$NQ~$EE?TU8&h{H>_6Xt_t-_zQG@rhtJdUUu-uBuAX4gPDg~&%t zJX6N{{)wZ`EZKg~Eg3JdUHUJ`0xvU(>c)HK&WxGd!lk065p?vW(He%X?ccu&?R&?FBU2KY$6)dKA__7rhz`Im(pfy3smajN56CHV$A{_`Ig07R`L#fmwOW zm@hXzovH3HN-5ie>`3uWtiFjMuFNuhoXl6+X4QW91EH}3Dl>jz%RM{zf7 zz>hVAT$#6Y_mpS7ioN2c)W+w+e!T}q&?a^?e^GLf)XxzXbYPuDgXU9>Vd%Uw{p%c> z{4%|bd=8s@#~j3cO0+vGAoI7xsGibqMkDaMaOFU}mwH<*<)dqLg2vYjc?Sx#V>zZf zu9x4}viX8nmeUWEhX(jtt3xsPbu}4t{D5yvHP}#D^%#h=dNf%qO}!DE%%XdeLy_N#>|Y2zTk2ZCy>N5jts7JF=m2qnU8dkc z80+Rb^?P6N_Xs^-U3y>oRMkg)yUcy~v!fykQ&oVTNibi`jsmNr>a9N|=JV{btaS3K zO^~F?hY^l*fhbyhtbAdQz;f zO>(TICX#}El6UhYV>_abd#EWrbReQ_RK0X!wUhF=Osiwkz%JMz82{w;xVop)_vjZ6 z+-S!b&R~1lo991B67_OlQyOYF8RdM;a(OwMoaOH$nfi+?p0sZqfq$fAARFEzDgNmZ zF2i1Tt8W4R7|`Y`Q(3)jBQ7InKp%@F<7|A7Z0h3_e5MWidfTmB8a80+3sa^j7|5`90W8v(3tVF~ z!;)TjAvoAMeg{iqb3<7E=B}{?UursTq$M?%yyr5yOZ^D~m|{#^oIWS1?OZpA@h|X2 z+8gjRCQs2_O7-h=n&b$ER?wMh1OLz@mxwQL|MNqN?_{m!1yMV`4t=^V=^uI>lg9mW zI`!mI<_HHMgr;QD87OTO%}Tlrz)qScs81Ndrzsz52R@zj7h!+^tYVcAM?%tM6RgT5 zQva}tKUHLy&3o;K?Ydo*ua{*|5^?|&C~t}M!Lfm`u=2$VvCcZPYT>}Wp;wm_{vISd zIKrGR^4i3J-~bHzTC4Tds|JDOKX24ulL-yT1n0<>PyKCV`S)ZT??`|U{n)7>9}gnb zC+XofF5coBEAnV6f;Spt_`%p@*wee`15KkDnR8UE`H%@1j^%QS>Yu*=^Nsf~{az*E z39V^V6lAxRBJiiTqqomF73vrvK^GrNfIwTMd+9HhdbN1hagt~m*Sm*zN;mrYZ<_N| zhvy5u7QC2@cf*a$G3o+H80^H}jkW>3bPogF6+28L+z;y2+#dNjd?+mboiW57HW9Hb zXT3%(F=dPl8=-cS;Su=-vO&P;SDUR-93AaLJ_~?grLBftwKx3xZSh%et2Q-2sE32U zCb^WnL|t@ux6XP24<}s8LSTHbRBJ7lmY0)+Xs;hGNu` zzi9_vj^5FD2eHFyYK0_{v;UmgvttR;JLTMuaHB&N;?#8QR*xqxkmouErt0fpeFHm{ z{(m?6eGZ-k;gci)Fl<8q7x>864HAY)<2cBuS(zH_Ho&Rl0d{}+{ zkk1Ann9aD1<3B7eWuU8c9=UISnfC**$6Q8zzYfGciEZ+~V#xK)JdemLXlBcyxSEp> z7QC9njo7EOPB>pBeUu+jLl;MfWZP{R#(y|!%b$N`~|4PZX_3)b5qrM0K0I%qqT4A!uAyz!4wRp~mu1 z_fv9R6fboS1ZXx2_Yf;;?0H_#I!kAZ5+a=)zK$Ui#954lbMiK=u_d&CVIWz5Aj3lT z67j<*^1%7(8zB*H_&PUi!0Yq-T(xUvx7oqr*rQc}{hh$eQ9%+f2(=0EjY<$Q(yt}Y zne1^`EPJKDXp0AcLh;B|X3z3IxeAz*sq%N2rxi(CJidpK;cCE1x24hYfvR%m42uPP zD&u8pu=jFa24>46Nz~EJoGhP27fOMF7@!+|)hAqE#S*l#L}L77h1agE`hkZR%ytti zBY+L8#%b$5K|0orQr3*Y1|#d@L=uJd?D)12a(3OBY~5{4G=O12nQjo?zf+M;tL1nv zDn@6Z_V}%+g?2a>EOrqIXam0bBUKhwHx0TXdX))!N`HunOG~C#3XYyk5hw?M8pn-I zQwpP|iLIRKhGx?BYd6v)$vbntpnDDZc`PSMGXsEEro2y^wF7qO@ib(4dC0F?As*N- z7aZ)`b9q{>2M4PBMWMDhlW4y*->ud4`;c;d_2m7zt`_U|IBJR&9hxpUiaR;#?@86M z?AosjpQ7|rQG49Dn{0?2MbSKTvOEC`ixAe%nH_X0`;4axk1L(A?1Lp^457eV4!o2X zs@Q?bfL$(u)4i4hfG0j$K~wgMXlJ82H7&C&iJ<)m#javS(!&j9fYIQiS_zAbU?aU{ zdUWM1ZCa|WsdBLW(aL+qi$owYP{Os^m_6{&K9gN2pQN-FzalB)7xJij;=he4DRe0R z0D&%BiEnp=+~0UB;~J=($XcZu_UZ?T1dRG zr|O(C4x&-W*go8jl?bQ!dByFEl7B6du#-}`O|IS2i2Jlt>^Hv$7d4C6A3w%|fF74O z!>nr)oZRV(=Y=I1Y8t0s5pxW0rfjFqvPbmMiQnk5=Wb70cuwj#Nd$SP=}nr1JQ6sU zypTJatyQujeLANG`IEI%RRl?EFe}_jq5?Gm;F#nn zTJb#(L`YEyVpLQf$xI$Arz{8vMSug<)PMbBw*YMZ^RJFJ|I$KzQ_eU zg{>jcm4V6(@^4hBJo5F5?kp$Ps9%3Nm{R3_65G77OBDLEjWx3ff@HdVnI>w3TOSNC z@olqSWMe^XwzWkvXS{w#M552(3#y?-s^>Cy?}h&%1M(wqaFbNt;%5GsvVcUga9o5U z!Dwi}^ynefxNV|0mfL7gUtgH*q-76RrJ^t3CPNRHK8pKQ5QnS zku+rdS)D}LQa!Pyv3rePz{_F1Dzcbb^4n^NHT-M}5CmtPgNKzj6n?T!$J35xEd2Yp z*~W-ib~0ehVn`(^g!prQws)Dm=m)K`Bl&QuWqt{OBmZD^@&XhL&5?Sh1A zu-EBid7ft^uE#77JYWjeU<0!F@rLq+0u>2{_!ESG--4PFfk`x99nt~;WzBff@YwZ` zio9$mxG*}D0nsQ7xwF7VM~gK*xR`9+D2jdxOo=XROdPEC2;Huc;JI${rjJ07td3lI zJcWA+y3oJf$67W3I*Qg{p(qUd+bB)IIR$2SVn@4z@En)0S?KifJJJ86>Uo+344IIL zrxf -
+ +
+ +
+
+
+
+
Table of Contents
+ +
+
+ +
+
+
+ +
+
+ + + +
+ +
+ {{!body}} +
+ + {{^_disableContribution}} +
+ {{#sourceurl}} + {{__global.improveThisDoc}} + {{/sourceurl}} + {{^sourceurl}}{{#docurl}} + {{__global.improveThisDoc}} + {{/docurl}}{{/sourceurl}} +
+ {{/_disableContribution}} + + {{^_disableNextArticle}} + + {{/_disableNextArticle}} + +
+ +
+ +
+
+ + {{#_enableSearch}} +
+ {{/_enableSearch}} + +
+
+
+ {{{_appFooter}}}{{^_appFooter}}Made with docfx{{/_appFooter}} +
+
+
+ + {{/redirect_url}} + diff --git a/VisualPinball.Unity/Documentation~/template/vpe/logo.svg b/VisualPinball.Unity/Documentation~/template/vpe/logo.svg index 6c66fa6a8..684a02604 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/logo.svg +++ b/VisualPinball.Unity/Documentation~/template/vpe/logo.svg @@ -1 +1,9 @@ - \ No newline at end of file + + diff --git a/VisualPinball.Unity/Documentation~/template/vpe/partials/affix.tmpl.partial b/VisualPinball.Unity/Documentation~/template/vpe/partials/affix.tmpl.partial deleted file mode 100644 index a31807940..000000000 --- a/VisualPinball.Unity/Documentation~/template/vpe/partials/affix.tmpl.partial +++ /dev/null @@ -1,25 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - diff --git a/VisualPinball.Unity/Documentation~/template/vpe/partials/head.tmpl.partial b/VisualPinball.Unity/Documentation~/template/vpe/partials/head.tmpl.partial deleted file mode 100644 index f63967c0a..000000000 --- a/VisualPinball.Unity/Documentation~/template/vpe/partials/head.tmpl.partial +++ /dev/null @@ -1,54 +0,0 @@ - - - - {{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/VisualPinball.Unity/Documentation~/template/vpe/partials/logo.tmpl.partial b/VisualPinball.Unity/Documentation~/template/vpe/partials/logo.tmpl.partial deleted file mode 100644 index 1bb847c87..000000000 --- a/VisualPinball.Unity/Documentation~/template/vpe/partials/logo.tmpl.partial +++ /dev/null @@ -1,5 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - - diff --git a/VisualPinball.Unity/Documentation~/template/vpe/partials/navbar.tmpl.partial b/VisualPinball.Unity/Documentation~/template/vpe/partials/navbar.tmpl.partial deleted file mode 100644 index 7f5e48e0c..000000000 --- a/VisualPinball.Unity/Documentation~/template/vpe/partials/navbar.tmpl.partial +++ /dev/null @@ -1,20 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - diff --git a/VisualPinball.Unity/Documentation~/template/vpe/styles/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css similarity index 85% rename from VisualPinball.Unity/Documentation~/template/vpe/styles/main.css rename to VisualPinball.Unity/Documentation~/template/vpe/public/main.css index cc0a74e32..cb31a2a87 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/styles/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -1,8 +1,11 @@ -html, +html, body { font-family: Inter, 'Segoe UI', Tahoma, Helvetica, sans-serif; - font-size: 100%; + font-size: 100%; +} +header .btn:hover { + background-color: #fff; } .btn.btn-default.active, .btn.btn-default:active { @@ -31,7 +34,7 @@ body { } #sidetoc .sidetoc.shiftup { - bottom: 0; + bottom: 0; } img[alt="Visual Pinball Engine"] { @@ -42,7 +45,7 @@ h1, h2 { font-weight: bold; } -.table-bordered, +.table-bordered, .table-bordered>tbody>tr>td, .table-bordered>tbody>tr>th, .table-bordered>tfoot>tr>td, @@ -52,5 +55,5 @@ h1, h2 { border-color: rgba(1,1,1,0.15); } .table-striped > tbody > tr:nth-of-type(odd) { - background-color: rgba(1,1,1,0.03) -} \ No newline at end of file + background-color: rgba(1,1,1,0.03) +} diff --git a/VisualPinball.Unity/Documentation~/template/vpe/styles/fonts.css b/VisualPinball.Unity/Documentation~/template/vpe/styles/fonts.css deleted file mode 100644 index 2ee636e79..000000000 --- a/VisualPinball.Unity/Documentation~/template/vpe/styles/fonts.css +++ /dev/null @@ -1,208 +0,0 @@ - - - -/* -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 100; - font-display: swap; - src: url("Inter-Thin.woff2?v=3.15") format("woff2"), - url("Inter-Thin.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 100; - font-display: swap; - src: url("Inter-ThinItalic.woff2?v=3.15") format("woff2"), - url("Inter-ThinItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 200; - font-display: swap; - src: url("Inter-ExtraLight.woff2?v=3.15") format("woff2"), - url("Inter-ExtraLight.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 200; - font-display: swap; - src: url("Inter-ExtraLightItalic.woff2?v=3.15") format("woff2"), - url("Inter-ExtraLightItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: url("Inter-Light.woff2?v=3.15") format("woff2"), - url("Inter-Light.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 300; - font-display: swap; - src: url("Inter-LightItalic.woff2?v=3.15") format("woff2"), - url("Inter-LightItalic.woff?v=3.15") format("woff"); -} -*/ -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url("/fonts/Inter-Regular.woff2?v=3.15") format("woff2"), - url("/fonts/Inter-Regular.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 400; - font-display: swap; - src: url("/fonts/Inter-Italic.woff2?v=3.15") format("woff2"), - url("/fonts/Inter-Italic.woff?v=3.15") format("woff"); -} -/* -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 500; - font-display: swap; - src: url("Inter-Medium.woff2?v=3.15") format("woff2"), - url("Inter-Medium.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 500; - font-display: swap; - src: url("Inter-MediumItalic.woff2?v=3.15") format("woff2"), - url("Inter-MediumItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 600; - font-display: swap; - src: url("Inter-SemiBold.woff2?v=3.15") format("woff2"), - url("Inter-SemiBold.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 600; - font-display: swap; - src: url("Inter-SemiBoldItalic.woff2?v=3.15") format("woff2"), - url("Inter-SemiBoldItalic.woff?v=3.15") format("woff"); -} -*/ -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: url("/fonts/Inter-Bold.woff2?v=3.15") format("woff2"), - url("/fonts/Inter-Bold.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 700; - font-display: swap; - src: url("/fonts/Inter-BoldItalic.woff2?v=3.15") format("woff2"), - url("/fonts/Inter-BoldItalic.woff?v=3.15") format("woff"); -} -/* -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 800; - font-display: swap; - src: url("Inter-ExtraBold.woff2?v=3.15") format("woff2"), - url("Inter-ExtraBold.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 800; - font-display: swap; - src: url("Inter-ExtraBoldItalic.woff2?v=3.15") format("woff2"), - url("Inter-ExtraBoldItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 900; - font-display: swap; - src: url("Inter-Black.woff2?v=3.15") format("woff2"), - url("Inter-Black.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 900; - font-display: swap; - src: url("Inter-BlackItalic.woff2?v=3.15") format("woff2"), - url("Inter-BlackItalic.woff?v=3.15") format("woff"); -} -*/ -/* ------------------------------------------------------- -Variable font. -Usage: - - html { font-family: 'Inter', sans-serif; } - @supports (font-variation-settings: normal) { - html { font-family: 'Inter var', sans-serif; } - } -*/ - -/* -@font-face { - font-family: 'Inter var'; - font-weight: 100 900; - font-display: swap; - font-style: normal; - font-named-instance: 'Regular'; - src: url("Inter-roman.var.woff2?v=3.15") format("woff2"); -} -@font-face { - font-family: 'Inter var'; - font-weight: 100 900; - font-display: swap; - font-style: italic; - font-named-instance: 'Italic'; - src: url("Inter-italic.var.woff2?v=3.15") format("woff2"); -} -*/ - -/* -------------------------------------------------------------------------- -[EXPERIMENTAL] Multi-axis, single variable font. - -Slant axis is not yet widely supported (as of February 2019) and thus this -multi-axis single variable font is opt-in rather than the default. - -When using this, you will probably need to set font-variation-settings -explicitly, e.g. - - * { font-variation-settings: "slnt" 0deg } - .italic { font-variation-settings: "slnt" 10deg } - -*/ -/* -@font-face { - font-family: 'Inter var experimental'; - font-weight: 100 900; - font-display: swap; - font-style: oblique 0deg 10deg; - src: url("Inter.var.woff2?v=3.15") format("woff2"); -} -*/ \ No newline at end of file diff --git a/VisualPinball.Unity/Documentation~/toc.yml b/VisualPinball.Unity/Documentation~/toc.yml index bdab2402d..20d6500f4 100644 --- a/VisualPinball.Unity/Documentation~/toc.yml +++ b/VisualPinball.Unity/Documentation~/toc.yml @@ -2,8 +2,5 @@ href: creators-guide/ - name: Plugins href: plugins/ -- name: API Documentation - href: api/ - homepage: api/index.md - name: Changelog href: /CHANGELOG.html diff --git a/VisualPinball.Unity/Documentation~/vpe.svg b/VisualPinball.Unity/Documentation~/vpe.svg index c47ac3a0a..ca26aec8d 100644 --- a/VisualPinball.Unity/Documentation~/vpe.svg +++ b/VisualPinball.Unity/Documentation~/vpe.svg @@ -1 +1,26 @@ - \ No newline at end of file + +AAAsZ2p1bWIAAAAeanVtZGMycGEAEQAQgAAAqgA4m3EDYzJwYQAAACxBanVtYgAAAEdqdW1kYzJtYQARABCAAACqADibcQN1cm46dXVpZDowMzY3MTJkZC0zN2U3LTQwNjctOGY3My1kNjJiNjc0OTA1OGUAAAABp2p1bWIAAAApanVtZGMyYXMAEQAQgAAAqgA4m3EDYzJwYS5hc3NlcnRpb25zAAAAAMpqdW1iAAAAJmp1bWRjYm9yABEAEIAAAKoAOJtxA2MycGEuYWN0aW9ucwAAAACcY2JvcqFnYWN0aW9uc4GjZmFjdGlvbmtjMnBhLmVkaXRlZG1zb2Z0d2FyZUFnZW50bUFkb2JlIEZpcmVmbHlxZGlnaXRhbFNvdXJjZVR5cGV4Rmh0dHA6Ly9jdi5pcHRjLm9yZy9uZXdzY29kZXMvZGlnaXRhbHNvdXJjZXR5cGUvdHJhaW5lZEFsZ29yaXRobWljTWVkaWEAAACsanVtYgAAAChqdW1kY2JvcgARABCAAACqADibcQNjMnBhLmhhc2guZGF0YQAAAAB8Y2JvcqVqZXhjbHVzaW9uc4GiZXN0YXJ0GMtmbGVuZ3RoGTs0ZG5hbWVuanVtYmYgbWFuaWZlc3RjYWxnZnNoYTI1NmRoYXNoWCBRy4VtZOjegibAlXtGwTG9jChO94sfwlcViv2jO9C6fWNwYWRJAAAAAAAAAAAAAAACC2p1bWIAAAAkanVtZGMyY2wAEQAQgAAAqgA4m3EDYzJwYS5jbGFpbQAAAAHfY2JvcqhoZGM6dGl0bGVvR2VuZXJhdGVkIEltYWdlaWRjOmZvcm1hdG1pbWFnZS9zdmcreG1samluc3RhbmNlSUR4LHhtcDppaWQ6OTAyOTU2MWUtYzBlYS00ZWMxLWE5MjQtZGM2MzZkYjlhN2Vmb2NsYWltX2dlbmVyYXRvcng2QWRvYmVfSWxsdXN0cmF0b3IvMjguMCBhZG9iZV9jMnBhLzAuNy42IGMycGEtcnMvMC4yNS4ydGNsYWltX2dlbmVyYXRvcl9pbmZvgb9kbmFtZXFBZG9iZSBJbGx1c3RyYXRvcmd2ZXJzaW9uZDI4LjD/aXNpZ25hdHVyZXgZc2VsZiNqdW1iZj1jMnBhLnNpZ25hdHVyZWphc3NlcnRpb25zgqJjdXJseCdzZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmFjdGlvbnNkaGFzaFgg66xm4WqDn3xgnOk59f7WI0GCp10rxJISEEb0ImTQK8GiY3VybHgpc2VsZiNqdW1iZj1jMnBhLmFzc2VydGlvbnMvYzJwYS5oYXNoLmRhdGFkaGFzaFggZTi6T30RavQw6UZvdKxtr4MkTknk06MnHdnGLSgwmD9jYWxnZnNoYTI1NgAAKEBqdW1iAAAAKGp1bWRjMmNzABEAEIAAAKoAOJtxA2MycGEuc2lnbmF0dXJlAAAAKBBjYm9y0oREoQE4JKNneDVjaGFpboJZBjMwggYvMIIEF6ADAgECAhAbWws72rDkXfLzDZ5U0drSMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxIjAgBgNVBAMTGUFkb2JlIFByb2R1Y3QgU2VydmljZXMgRzMwHhcNMjMwMjAxMDAwMDAwWhcNMjQwMjAxMjM1OTU5WjCBoTERMA8GA1UEAwwIY2FpLXByb2QxHDAaBgNVBAsME0NvbnRlbnQgQ3JlZGVudGlhbHMxEzARBgNVBAoMCkFkb2JlIEluYy4xETAPBgNVBAcMCFNhbiBKb3NlMRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzEkMCIGCSqGSIb3DQEJARYVZ3JwLWNhaS1vcHNAYWRvYmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA79MAp32GPZZBw7MpK0xuxWJZ2BwXMrmpbg+bvVC487/hbE1ji4PDYa8/UU8SPRHgW7t1pu3+L6j7EGH8ZBKdMCGug1ZhDmYWwHkX24cm1kPw+Fr73JOJhGUfkGZk6SJ+x1+tYG7TBR5SVMZGAXLSKALfUwQBW8/XeSINlhtG7B9/W+v/FEl5yCJOBQenbQUU9cXhMEg7cDndWAaV1zQSZkVh1zSWWfOaH9rQU3rIP5DL06ziScWA2fe1ONesHL21aJpXnrPjV1GN/2QeMR/jbGYpbO5tWy9r9oUpx4i6KmXlCpJWx1Jk+GaY62QnbbiLFpuY9jz1yq+xylLgm2UlwQIDAQAFo4IBjDCCAYgwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwHgYDVR0lBBcwFQYJKoZIhvcvAQEMBggrBgEFBQcDBDCBjgYDVR0gBIGGMIGDMIGABgkqhkiG9y8BAgMwczBxBggrBgEFBQcCAjBlDGNZb3UgYXJlIG5vdCBwZXJtaXR0ZWQgdG8gdXNlIHRoaXMgTGljZW5zZSBDZXJ0aWZpY2F0ZSBleGNlcHQgYXMgcGVybWl0dGVkIGJ5IHRoZSBsaWNlbnNlIGFncmVlbWVudC4wXQYDVR0fBFYwVDBSoFCgToZMaHR0cDovL3BraS1jcmwuc3ltYXV0aC5jb20vY2FfN2E1YzNhMGM3MzExNzQwNmFkZDE5MzEyYmMxYmMyM2YvTGF0ZXN0Q1JMLmNybDA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9wa2ktb2NzcC5zeW1hdXRoLmNvbTAfBgNVHSMEGDAWgBRXKXoyTcz+5DVOwB8kc85zU6vfajANBgkqhkiG9w0BAQsFAAOCAgEAV45Rmt8gCvxoo5+p/yTVPRWZu9jD+r3OXM61nvctE/hGsLkb4aQ+RHYtU515K6XvLDJIEo0xnW2PshoavM5QlkHlzdf2lqNy/V69bjcWP6FaS59Llln53ye8kfYCpf8qDH4Y8nU+LdX1x4vzIX4a1klUR6l9lN9VBRs/3tvfD9pL/r6oc6SFKNW4/o4m7aDyzDEHAjk7SoiTk4eKN1UmacEAxEQs6PdTZBfi52Y8GJenxOVEiJIP6AqKJl8Uj6aMMmw63ESfYpW7SXBEePPyxoMM7/3OzmHa6J+D5xF5tRZDmlY/kEX+zsIjU4s6J4SMy0eVX6dEBzlr/2z87woz0Hfl69EONN9lpUsUMKLLTUwD7aFQFODgsFR9xHId/HpidNP+n5Awna+zDfP+J9i0jazFL2gRGXZi6gwgZztNnWxa5qYN6U3NBakUOBi//PKY0TUjMubVPUqEJ0ghmKiLI3y/AM4DxBol10YAAWHNbl3nH+P3msm9ytjD7O4Z1k21CqRxySMMaXTd70xnWTVqc/TsX7qN3hC0JZE7wAh4KpGl4vxQGpx3uTwoZ+n69f+HDRfIKA9G7jwKYEt888Ko0Ycax/CEsD3yZ/Cas7qzGiwzJ53NfLR81IjLV+943+qF4e76AsV/0+A95xT5cVN6JtnKXC0NVneNNusdfK5UhkdZBqUwggahMIIEiaADAgECAhAMqLZUe4nm0gaJdc2Lm4niMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxGTAXBgNVBAMTEEFkb2JlIFJvb3QgQ0EgRzIwHhcNMTYxMTI5MDAwMDAwWhcNNDExMTI4MjM1OTU5WjB1MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMSIwIAYDVQQDExlBZG9iZSBQcm9kdWN0IFNlcnZpY2VzIEczMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtx8uvb0Js1xIbP4Mg65sAepReCWkgD6Jp7GyiGTa9ol2gfn5HfOV/HiYjZiOz+TuHFU+DXNad86xEqgVeGVMlvIHGe/EHcKBxvEDXdlTXB5zIEkfl0/SGn7J6vTX8MNybfSi95eQDUOZ9fjCaq+PBFjS5ZfeNmzi/yR+MsA0jKKoWarSRCFFFBpUFQWfAgLyXOyxOnXQOQudjxNj6Wu0X0IB13+IH11WcKcWEWXM4j4jh6hLy29Cd3EoVG3oxcVenMF/EMgD2tXjx4NUbTNB1/g9+MR6Nw5Mhp5k/g3atNExAxhtugC+T3SDShSEJfs2quiiRUHtX3RhOcK1s1OJgT5s2s9xGy5/uxVpcAIaK2KiDJXW3xxN8nXPmk1NSVu/mxtfapr4TvSJbhrU7UA3qhQY9n4On2sbH1X1Tw+7LTek8KCA5ZDghOERPiIp/Jt893qov1bE5rJkagcVg0Wqjh89NhCaBA8VyRt3ovlGyCKdNV2UL3bn5vdFsTk7qqmp9makz1/SuVXYxIf6L6+8RXOatXWaPkmucuLE1TPOeP7S1N5JToFCs80l2D2EtxoQXGCR48K/cTUR5zV/fQ+hdIOzoo0nFn77Y8Ydd2k7/x9BE78pmoeMnw6VXYfXCuWEgj6p7jpbLoxQMoWMCVzlg72WVNhJFlSw4aD8fc6ezeECAwEAAaOCATQwggEwMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5hZG9iZS5jb20vYWRvYmVyb290ZzIuY3JsMA4GA1UdDwEB/wQEAwIBBjAUBgNVHSUEDTALBgkqhkiG9y8BAQcwVwYDVR0gBFAwTjBMBgkqhkiG9y8BAgMwPzA9BggrBgEFBQcCARYxaHR0cHM6Ly93d3cuYWRvYmUuY29tL21pc2MvcGtpL3Byb2Rfc3ZjZV9jcHMuaHRtbDAkBgNVHREEHTAbpBkwFzEVMBMGA1UEAxMMU1lNQy00MDk2LTMzMB0GA1UdDgQWBBRXKXoyTcz+5DVOwB8kc85zU6vfajAfBgNVHSMEGDAWgBSmHOFtVCRMqI9Icr9uqYzV5Owx1DANBgkqhkiG9w0BAQsFAAOCAgEAcc7lB4ym3C3cyOA7ZV4AkoGV65UgJK+faThdyXzxuNqlTQBlOyXBGFyevlm33BsGO1mDJfozuyLyT2+7IVxWFvW5yYMV+5S1NeChMXIZnCzWNXnuiIQSdmPD82TEVCkneQpFET4NDwSxo8/ykfw6Hx8fhuKz0wjhjkWMXmK3dNZXIuYVcbynHLyJOzA+vWU3sH2T0jPtFp7FN39GZne4YG0aVMlnHhtHhxaXVCiv2RVoR4w1QtvKHQpzfPObR53Cl74iLStGVFKPwCLYRSpYRF7J6vVS/XxW4LzvN2b6VEKOcvJmN3LhpxFRl3YYzW+dwnwtbuHW6WJlmjffbLm1MxLFGlG95aCz31X8wzqYNsvb9+5AXcv8Ll69tLXmO1OtsY/3wILNUEp4VLZTE3wqm3n8hMnClZiiKyZCS7L4E0mClbx+BRSMH3eVo6jgve41/fK3FQM4QCNIkpGs7FjjLy+ptC+JyyWqcfvORrFV/GOgB5hD+G5ghJcIpeigD/lHsCRYsOa5sFdqREhwIWLmSWtNwfLZdJ3dkCc7yRpm3gal6qRfTkYpxTNxxKyvKbkaJDoxR9vtWrC3iNrQd9VvxC3TXtuzoHbqumeqgcAqefWF9u6snQ4Q9FkXzeuJArNuSvPIhgBjVtggH0w0vm/lmCQYiC/Y12GeCxfgYlL33btmc2lnVHN0oWl0c3RUb2tlbnOBoWN2YWxZF0Ewghc9MAMCAQAwghc0BgkqhkiG9w0BBwKgghclMIIXIQIBAzEPMA0GCWCGSAFlAwQCAQUAMIGDBgsqhkiG9w0BCRABBKB0BHIwcAIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIIOmDi9fuuYnRafLHrNjXnTO4/RQb5wEjAWJ0FYc/zqsAhEA34n7Dzh2JYgb2cBdNLCI5BgPMjAyMzEwMTkyMTUxNTdaAgkA4SALCeL5iRCgghMJMIIGwjCCBKqgAwIBAgIQBUSv85SdCDmmv9s/X+VhFjANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTIzMDcxNDAwMDAwMFoXDTM0MTAxMzIzNTk1OVowSDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKNTRYcdg45brD5UsyPgz5/X5dLnXaEOCdwvSKOXejsqnGfcYhVYwamTEafNqrJq3RApih5iY2nTWJw1cb86l+uUUI8cIOrHmjsvlmbjaedp/lvD1isgHMGXlLSlUIHyz8sHpjBoyoNC2vx/CSSUpIIa2mq62DvKXd4ZGIX7ReoNYWyd/nFexAaaPPDFLnkPG2ZS48jWPl/aQ9OE9dDH9kgtXkV1lnX+3RChG4PBuOZSlbVH13gpOWvgeFmX40QrStWVzu8IF+qCZE3/I+PKhu60pCFkcOvV5aDaY7Mu6QXuqvYk9R28mxyyt1/f8O52fTGZZUdVnUokL6wrl76f5P17cz4y7lI0+9S769SgLDSb495uZBkHNwGRDxy1Uc2qTGaDiGhiu7xBG3gZbeTZD+BYQfvYsSzhUa+0rRUGFOpiCBPTaR58ZE2dD9/O0V6MqqtQFcmzyrzXxDtoRKOlO0L9c33u3Qr/eTQQfqZcClhMAD6FaXXHg2TWdc2PEnZWpST618RrIbroHzSYLzrqawGw9/sqhux7UjipmAmhcbJsca8+uG+W1eEQE/5hRwqM/vC2x9XH3mwk8L9CgsqgcT2ckpMEtGlwJw1Pt7U20clfCKRwo+wK8REuZODLIivK8SgTIUlRfgZm0zu++uuRONhRB8qUt+JQofM604qDy0B7AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFKW27xPn783QZKHVVqllMaPe1eNJMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBAIEa1t6gqbWYF7xwjU+KPGic2CX/yyzkzepdIpLsjCICqbjPgKjZ5+PF7SaCinEvGN1Ott5s1+FgnCvt7T1IjrhrunxdvcJhN2hJd6PrkKoS1yeF844ektrCQDifXcigLiV4JZ0qBXqEKZi2V3mP2yZWK7Dzp703DNiYdk9WuVLCtp04qYHnbUFcjGnRuSvExnvPnPp44pMadqJpddNQ5EQSviANnqlE0PjlSXcIWiHFtM+YlRpUurm8wWkZus8W8oM3NG6wQSbd3lqXTzON1I13fXVFoaVYJmoDRd7ZULVQjK9WvUzF4UbFKNOt50MAcN7MmJ4ZiQPq1JE3701S88lgIcRWR+3aEUuMMsOI5ljitts++V+wQtaP4xeR0arAVeOGv6wnLEHQmjNKqDbUuXKWfpd5OEhfysLcPTLfddY2Z1qJ+Panx+VPNTwAvb6cKmx5AdzaROY63jg7B145WPR8czFVoIARyxQMfq68/qTreWWqaNYiyjvrmoI1VygWy2nyMpqy0tg6uLFGhmu6F/3Ed2wVbK6rr3M66ElGt9V/zLY4wNjsHPW2obhDLN9OTH0eaHDAdwrUAuBcYLso/zjlUlrWrBciI0707NMX+1Br/wd3H3GXREHJuEbTbDJ8WC9nR2XlG3O2mflrLAZG70Ee8PBf4NvZrZCARK+AEEGKMIIGrjCCBJagAwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUDxPKRN6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1ATCyZzlm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW1OcoLevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS8nZH92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jBZHRAp8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCYJn+gGkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucfWmyU8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLcGEh/FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNFYLwjjVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI+RQQEgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjASvUaetdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJLKftwig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgWvalWzxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2MvGQmh2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSumScbqyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJxLafzYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un8WbDQc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SVe+0KXzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4k9Tm8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJDwq9gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr5n8apIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBY0wggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZIhvcNAQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVowYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zCpyUuySE98orYWcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J58soR0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6Zu53yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQecN4x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4bA3VdeGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCUtNJhbesz2cXfSwQAzH0clcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvoZKYz0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCPorF+CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8jLfR+cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDGCA3YwggNyAgEBMHcwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQBUSv85SdCDmmv9s/X+VhFjANBglghkgBZQMEAgEFAKCB0TAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIzMTAxOTIxNTE1N1owKwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQUZvArMsLCyQ+CXc6qisnGTxmcz0AwLwYJKoZIhvcNAQkEMSIEIOA/0nBy5DVVGkO7Ul9gt8qjHnvPyu9xLb0wMN7Yzs0uMDcGCyqGSIb3DQEJEAIvMSgwJjAkMCIEINL25G3tdCLM0dRAV2hBNm+CitpVmq4zFq9NGprUDHgoMA0GCSqGSIb3DQEBAQUABIICAEzB5v31oQObu2ETlzsQY8mVOphH18M7c9aD+DOXz1tUc/k1ttaBnKOm42BKsdTCkTmluGDNnd+Mk672MP6VC4oKrjlR1cI5imNFf5srmp8Q8RcHZxT2VEO7rfTido1Dg4zx8uq4lMv/p69Bc+DZb2nGTUC7Gf6cvMtQnQWgpMZOsvGVaUtuJL7V3jk2a2CebjhweTZUx+pWLBPb5hg776X4scUXDN9BOF8BeAGXtagFo10zbo4ttr4IoCn9JNAdVHT0706cVL/LF1ckDRQVYrLsvCjVw9kE3fDWWeD/st/2wBiL3nvUjnGxZho1gsozOenQLTArjEZSTDCFzAXLZwbfQNnAK67MqdeJd6iBmaFNgXpADbK0lUs39oxRqabVYsht+H1Onm7WxqmENoZAEF53y7jFMCYq9G8DGa7jqnCQfRBCTj1VN/qV73ZtkwkuhY0EAd8waPg+IOkY0+Rt2MkWMfiQbVLn5RQcnfSs6lJGs1WAofvVeeWqd4BZ/XxbfuTs3kItzFQyfSMJGVt7thAvdFuIp9CGdZjXLRRABxomSj7YfOjNRak3kvK/LApdnaosPJILFZYPwj3/B7Jjgl0GYrNIcK1IFz+JLvM3g/7ppPY5hHPSMHojHtkzzJeE6jPB3Tq0XnoPyrG+mk5DmwxlQjtcNMaBFTe2lCTXounYY3BhZFkCsgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPZZAQAMB3yr2NRna25aL/kkNcUWBa54HxmPICMif5UIddMz3rRqt4abkvVlrVotfUbm/9rbEsmprBQa7X+G47IkXbh35I+wG7H233UIunLEDbPBipbZL4C5P2CSKvWYYgFy0NhAtt7coS34N6+lU+ZmaPD9p+rQyHvf7I4WE3s5ERmw3SqmE2peBiPP1FbSXWXzF5roS8eJXuReVpDd+86qzsyiH5vFq4fmvXhzVcS7hmHxWEpBu1sHpVxZx82nAhhsQIyrx/Ck72FVWP6/Cnnem0Ex6RZ4HFPHCuh5iMMqJc0XL28UsfxQj6FA4qGGYKfvSkJ4cTErZFnkj/wmgNlU/QXk + + + + + + + + + VISUAL PINBALL ENGINE + \ No newline at end of file From fe6af6ba3e77f24e527b9392f9858f17ceaec18b Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 20 Oct 2023 21:37:27 +0200 Subject: [PATCH 121/159] doc: Add Github link. --- VisualPinball.Unity/Documentation~/docfx.json | 4 +- .../template/vpe/layout/_master.tmpl | 16 ++++ .../template/vpe/public/main.css | 86 ++++++++++--------- 3 files changed, 64 insertions(+), 42 deletions(-) diff --git a/VisualPinball.Unity/Documentation~/docfx.json b/VisualPinball.Unity/Documentation~/docfx.json index c64cd67b1..c5d29bcf6 100644 --- a/VisualPinball.Unity/Documentation~/docfx.json +++ b/VisualPinball.Unity/Documentation~/docfx.json @@ -46,8 +46,8 @@ "_appFaviconPath": "favicon.png", "_gitContribute": { "branch": "master" - } - + }, + "_enableSearch": true }, "sitemap":{ "baseUrl": "https://docs.visualpinball.org/", diff --git a/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl b/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl index 11a9fbd76..3989cdfb1 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl +++ b/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl @@ -37,6 +37,19 @@ {{/redirect_url}} + {{^redirect_url}} @@ -80,6 +93,9 @@ {{/_enableSearch}} + + + diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css index cb31a2a87..f16e77074 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -4,56 +4,62 @@ body { font-size: 100%; } -header .btn:hover { - background-color: #fff; +.navbar-github { + order: 100; + margin-left: 10px; + margin-top: 4px; } - -.btn.btn-default.active, .btn.btn-default:active { - outline: 0; - -webkit-box-shadow: none; - box-shadow: none; - background-color: rgba(1,1,1,0.08); -} - -.navbar-brand > svg { - margin-top: 6px; -} - .navbar-github > svg { - margin-top: 8px; fill: #ccc; } -.navbar-default { - background-color: rgba(1,1,1,0.05); - border-color: rgba(1,1,1,0.1); -} +/*header .btn:hover {*/ +/* background-color: #fff;*/ +/*}*/ -#sidetoc .sidefilter { - top: 94px; -} +/*.btn.btn-default.active, .btn.btn-default:active {*/ +/* outline: 0;*/ +/* -webkit-box-shadow: none;*/ +/* box-shadow: none;*/ +/* background-color: rgba(1,1,1,0.08);*/ +/*}*/ -#sidetoc .sidetoc.shiftup { - bottom: 0; -} +/*.navbar-brand > svg {*/ +/* margin-top: 6px;*/ +/*}*/ -img[alt="Visual Pinball Engine"] { - margin-top: 15px; -} + + +/*.navbar-default {*/ +/* background-color: rgba(1,1,1,0.05);*/ +/* border-color: rgba(1,1,1,0.1);*/ +/*}*/ + +/*#sidetoc .sidefilter {*/ +/* top: 94px;*/ +/*}*/ + +/*#sidetoc .sidetoc.shiftup {*/ +/* bottom: 0;*/ +/*}*/ + +/*img[alt="Visual Pinball Engine"] {*/ +/* margin-top: 15px;*/ +/*}*/ h1, h2 { font-weight: bold; } -.table-bordered, -.table-bordered>tbody>tr>td, -.table-bordered>tbody>tr>th, -.table-bordered>tfoot>tr>td, -.table-bordered>tfoot>tr>th, -.table-bordered>thead>tr>td, -.table-bordered>thead>tr>th { - border-color: rgba(1,1,1,0.15); -} -.table-striped > tbody > tr:nth-of-type(odd) { - background-color: rgba(1,1,1,0.03) -} +/*.table-bordered,*/ +/*.table-bordered>tbody>tr>td,*/ +/*.table-bordered>tbody>tr>th,*/ +/*.table-bordered>tfoot>tr>td,*/ +/*.table-bordered>tfoot>tr>th,*/ +/*.table-bordered>thead>tr>td,*/ +/*.table-bordered>thead>tr>th {*/ +/* border-color: rgba(1,1,1,0.15);*/ +/*}*/ +/*.table-striped > tbody > tr:nth-of-type(odd) {*/ +/* background-color: rgba(1,1,1,0.03)*/ +/*}*/ From 81839bb77ea9f677fb773eba3c9bfe1d580aae63 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 21 Oct 2023 22:18:26 +0200 Subject: [PATCH 122/159] doc: Move fonts to separate folder and edit button to affix. --- .../template/vpe/fonts/inter.css | 200 ---------------- .../template/vpe/layout/_master.tmpl | 30 +-- .../vpe/{ => public}/fonts/Inter-Black.woff | Bin .../vpe/{ => public}/fonts/Inter-Black.woff2 | Bin .../{ => public}/fonts/Inter-BlackItalic.woff | Bin .../fonts/Inter-BlackItalic.woff2 | Bin .../vpe/{ => public}/fonts/Inter-Bold.woff | Bin .../vpe/{ => public}/fonts/Inter-Bold.woff2 | Bin .../{ => public}/fonts/Inter-BoldItalic.woff | Bin .../{ => public}/fonts/Inter-BoldItalic.woff2 | Bin .../{ => public}/fonts/Inter-ExtraBold.woff | Bin .../{ => public}/fonts/Inter-ExtraBold.woff2 | Bin .../fonts/Inter-ExtraBoldItalic.woff | Bin .../fonts/Inter-ExtraBoldItalic.woff2 | Bin .../{ => public}/fonts/Inter-ExtraLight.woff | Bin .../{ => public}/fonts/Inter-ExtraLight.woff2 | Bin .../fonts/Inter-ExtraLightItalic.woff | Bin .../fonts/Inter-ExtraLightItalic.woff2 | Bin .../vpe/{ => public}/fonts/Inter-Italic.woff | Bin .../vpe/{ => public}/fonts/Inter-Italic.woff2 | Bin .../vpe/{ => public}/fonts/Inter-Light.woff | Bin .../vpe/{ => public}/fonts/Inter-Light.woff2 | Bin .../{ => public}/fonts/Inter-LightItalic.woff | Bin .../fonts/Inter-LightItalic.woff2 | Bin .../vpe/{ => public}/fonts/Inter-Medium.woff | Bin .../vpe/{ => public}/fonts/Inter-Medium.woff2 | Bin .../fonts/Inter-MediumItalic.woff | Bin .../fonts/Inter-MediumItalic.woff2 | Bin .../vpe/{ => public}/fonts/Inter-Regular.woff | Bin .../{ => public}/fonts/Inter-Regular.woff2 | Bin .../{ => public}/fonts/Inter-SemiBold.woff | Bin .../{ => public}/fonts/Inter-SemiBold.woff2 | Bin .../fonts/Inter-SemiBoldItalic.woff | Bin .../fonts/Inter-SemiBoldItalic.woff2 | Bin .../vpe/{ => public}/fonts/Inter-Thin.woff | Bin .../vpe/{ => public}/fonts/Inter-Thin.woff2 | Bin .../{ => public}/fonts/Inter-ThinItalic.woff | Bin .../{ => public}/fonts/Inter-ThinItalic.woff2 | Bin .../{ => public}/fonts/Inter-italic.var.woff2 | Bin .../{ => public}/fonts/Inter-roman.var.woff2 | Bin .../vpe/{ => public}/fonts/Inter.var.woff2 | Bin .../template/vpe/public/main.css | 214 +++++++++++++++++- .../Documentation~/template/vpe/token.json | 3 + 43 files changed, 228 insertions(+), 219 deletions(-) delete mode 100644 VisualPinball.Unity/Documentation~/template/vpe/fonts/inter.css rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Black.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Black.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-BlackItalic.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-BlackItalic.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Bold.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Bold.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-BoldItalic.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-BoldItalic.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-ExtraBold.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-ExtraBold.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-ExtraBoldItalic.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-ExtraBoldItalic.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-ExtraLight.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-ExtraLight.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-ExtraLightItalic.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-ExtraLightItalic.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Italic.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Italic.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Light.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Light.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-LightItalic.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-LightItalic.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Medium.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Medium.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-MediumItalic.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-MediumItalic.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Regular.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Regular.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-SemiBold.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-SemiBold.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-SemiBoldItalic.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-SemiBoldItalic.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Thin.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-Thin.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-ThinItalic.woff (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-ThinItalic.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-italic.var.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter-roman.var.woff2 (100%) rename VisualPinball.Unity/Documentation~/template/vpe/{ => public}/fonts/Inter.var.woff2 (100%) create mode 100644 VisualPinball.Unity/Documentation~/template/vpe/token.json diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/inter.css b/VisualPinball.Unity/Documentation~/template/vpe/fonts/inter.css deleted file mode 100644 index 66c7fb69c..000000000 --- a/VisualPinball.Unity/Documentation~/template/vpe/fonts/inter.css +++ /dev/null @@ -1,200 +0,0 @@ -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 100; - font-display: swap; - src: url("Inter-Thin.woff2?v=3.15") format("woff2"), - url("Inter-Thin.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 100; - font-display: swap; - src: url("Inter-ThinItalic.woff2?v=3.15") format("woff2"), - url("Inter-ThinItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 200; - font-display: swap; - src: url("Inter-ExtraLight.woff2?v=3.15") format("woff2"), - url("Inter-ExtraLight.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 200; - font-display: swap; - src: url("Inter-ExtraLightItalic.woff2?v=3.15") format("woff2"), - url("Inter-ExtraLightItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: url("Inter-Light.woff2?v=3.15") format("woff2"), - url("Inter-Light.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 300; - font-display: swap; - src: url("Inter-LightItalic.woff2?v=3.15") format("woff2"), - url("Inter-LightItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url("Inter-Regular.woff2?v=3.15") format("woff2"), - url("Inter-Regular.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 400; - font-display: swap; - src: url("Inter-Italic.woff2?v=3.15") format("woff2"), - url("Inter-Italic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 500; - font-display: swap; - src: url("Inter-Medium.woff2?v=3.15") format("woff2"), - url("Inter-Medium.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 500; - font-display: swap; - src: url("Inter-MediumItalic.woff2?v=3.15") format("woff2"), - url("Inter-MediumItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 600; - font-display: swap; - src: url("Inter-SemiBold.woff2?v=3.15") format("woff2"), - url("Inter-SemiBold.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 600; - font-display: swap; - src: url("Inter-SemiBoldItalic.woff2?v=3.15") format("woff2"), - url("Inter-SemiBoldItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: url("Inter-Bold.woff2?v=3.15") format("woff2"), - url("Inter-Bold.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 700; - font-display: swap; - src: url("Inter-BoldItalic.woff2?v=3.15") format("woff2"), - url("Inter-BoldItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 800; - font-display: swap; - src: url("Inter-ExtraBold.woff2?v=3.15") format("woff2"), - url("Inter-ExtraBold.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 800; - font-display: swap; - src: url("Inter-ExtraBoldItalic.woff2?v=3.15") format("woff2"), - url("Inter-ExtraBoldItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 900; - font-display: swap; - src: url("Inter-Black.woff2?v=3.15") format("woff2"), - url("Inter-Black.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 900; - font-display: swap; - src: url("Inter-BlackItalic.woff2?v=3.15") format("woff2"), - url("Inter-BlackItalic.woff?v=3.15") format("woff"); -} - -/* ------------------------------------------------------- -Variable font. -Usage: - - html { font-family: 'Inter', sans-serif; } - @supports (font-variation-settings: normal) { - html { font-family: 'Inter var', sans-serif; } - } -*/ -@font-face { - font-family: 'Inter var'; - font-weight: 100 900; - font-display: swap; - font-style: normal; - font-named-instance: 'Regular'; - src: url("Inter-roman.var.woff2?v=3.15") format("woff2"); -} -@font-face { - font-family: 'Inter var'; - font-weight: 100 900; - font-display: swap; - font-style: italic; - font-named-instance: 'Italic'; - src: url("Inter-italic.var.woff2?v=3.15") format("woff2"); -} - - -/* -------------------------------------------------------------------------- -[EXPERIMENTAL] Multi-axis, single variable font. - -Slant axis is not yet widely supported (as of February 2019) and thus this -multi-axis single variable font is opt-in rather than the default. - -When using this, you will probably need to set font-variation-settings -explicitly, e.g. - - * { font-variation-settings: "slnt" 0deg } - .italic { font-variation-settings: "slnt" 10deg } - -*/ -@font-face { - font-family: 'Inter var experimental'; - font-weight: 100 900; - font-display: swap; - font-style: oblique 0deg 10deg; - src: url("Inter.var.woff2?v=3.15") format("woff2"); -} diff --git a/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl b/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl index 3989cdfb1..f29202736 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl +++ b/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl @@ -77,7 +77,7 @@
-
+
@@ -130,17 +130,6 @@ {{!body}} - {{^_disableContribution}} -
- {{#sourceurl}} - {{__global.improveThisDoc}} - {{/sourceurl}} - {{^sourceurl}}{{#docurl}} - {{__global.improveThisDoc}} - {{/docurl}}{{/sourceurl}} -
- {{/_disableContribution}} - {{^_disableNextArticle}} {{/_disableNextArticle}} @@ -149,15 +138,26 @@
+ + {{^_disableContribution}} +
+ {{#sourceurl}} + {{__global.improveThisDoc}} + {{/sourceurl}} + {{^sourceurl}}{{#docurl}} + {{__global.improveThisDoc}} + {{/docurl}}{{/sourceurl}} +
+ {{/_disableContribution}}
{{#_enableSearch}} -
+
{{/_enableSearch}}
-
+
{{{_appFooter}}}{{^_appFooter}}Made with docfx{{/_appFooter}}
diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Black.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Black.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Black.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Black.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Black.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Black.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Black.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Black.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-BlackItalic.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-BlackItalic.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-BlackItalic.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-BlackItalic.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-BlackItalic.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-BlackItalic.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-BlackItalic.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-BlackItalic.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Bold.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Bold.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Bold.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Bold.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Bold.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Bold.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Bold.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Bold.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-BoldItalic.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-BoldItalic.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-BoldItalic.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-BoldItalic.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-BoldItalic.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-BoldItalic.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-BoldItalic.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-BoldItalic.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraBold.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraBold.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraBold.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraBold.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraBold.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraBold.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraBold.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraBold.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraBoldItalic.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraBoldItalic.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraBoldItalic.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraBoldItalic.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraBoldItalic.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraBoldItalic.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraBoldItalic.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraBoldItalic.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraLight.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraLight.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraLight.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraLight.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraLight.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraLight.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraLight.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraLight.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraLightItalic.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraLightItalic.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraLightItalic.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraLightItalic.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraLightItalic.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraLightItalic.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ExtraLightItalic.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ExtraLightItalic.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Italic.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Italic.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Italic.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Italic.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Italic.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Italic.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Italic.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Italic.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Light.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Light.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Light.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Light.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Light.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Light.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Light.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Light.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-LightItalic.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-LightItalic.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-LightItalic.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-LightItalic.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-LightItalic.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-LightItalic.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-LightItalic.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-LightItalic.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Medium.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Medium.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Medium.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Medium.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Medium.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Medium.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Medium.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Medium.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-MediumItalic.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-MediumItalic.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-MediumItalic.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-MediumItalic.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-MediumItalic.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-MediumItalic.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-MediumItalic.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-MediumItalic.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Regular.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Regular.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Regular.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Regular.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Regular.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Regular.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Regular.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Regular.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-SemiBold.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-SemiBold.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-SemiBold.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-SemiBold.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-SemiBold.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-SemiBold.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-SemiBold.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-SemiBold.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-SemiBoldItalic.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-SemiBoldItalic.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-SemiBoldItalic.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-SemiBoldItalic.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-SemiBoldItalic.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-SemiBoldItalic.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-SemiBoldItalic.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-SemiBoldItalic.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Thin.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Thin.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Thin.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Thin.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Thin.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Thin.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-Thin.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-Thin.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ThinItalic.woff b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ThinItalic.woff similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ThinItalic.woff rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ThinItalic.woff diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ThinItalic.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ThinItalic.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-ThinItalic.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-ThinItalic.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-italic.var.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-italic.var.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-italic.var.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-italic.var.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-roman.var.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-roman.var.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter-roman.var.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter-roman.var.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter.var.woff2 b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter.var.woff2 similarity index 100% rename from VisualPinball.Unity/Documentation~/template/vpe/fonts/Inter.var.woff2 rename to VisualPinball.Unity/Documentation~/template/vpe/public/fonts/Inter.var.woff2 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css index f16e77074..a8aa64b48 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -13,6 +13,15 @@ body { fill: #ccc; } +h1, h2 { + font-weight: bold; +} + +.affix h5 { /* "In this article" */ + font-weight: 600; + letter-spacing: normal !important; +} + /*header .btn:hover {*/ /* background-color: #fff;*/ /*}*/ @@ -47,10 +56,6 @@ body { /* margin-top: 15px;*/ /*}*/ -h1, h2 { - font-weight: bold; -} - /*.table-bordered,*/ /*.table-bordered>tbody>tr>td,*/ /*.table-bordered>tbody>tr>th,*/ @@ -63,3 +68,204 @@ h1, h2 { /*.table-striped > tbody > tr:nth-of-type(odd) {*/ /* background-color: rgba(1,1,1,0.03)*/ /*}*/ + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url("fonts/Inter-Thin.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Thin.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url("fonts/Inter-ThinItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-ThinItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 200; + font-display: swap; + src: url("fonts/Inter-ExtraLight.woff2?v=3.15") format("woff2"), + url("fonts/Inter-ExtraLight.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 200; + font-display: swap; + src: url("fonts/Inter-ExtraLightItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-ExtraLightItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url("fonts/Inter-Light.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Light.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url("fonts/Inter-LightItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-LightItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("fonts/Inter-Regular.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Regular.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url("fonts/Inter-Italic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Italic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url("fonts/Inter-Medium.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Medium.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url("fonts/Inter-MediumItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-MediumItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url("fonts/Inter-SemiBold.woff2?v=3.15") format("woff2"), + url("fonts/Inter-SemiBold.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url("fonts/Inter-SemiBoldItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-SemiBoldItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url("fonts/Inter-Bold.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Bold.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url("fonts/Inter-BoldItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-BoldItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 800; + font-display: swap; + src: url("fonts/Inter-ExtraBold.woff2?v=3.15") format("woff2"), + url("fonts/Inter-ExtraBold.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 800; + font-display: swap; + src: url("fonts/Inter-ExtraBoldItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-ExtraBoldItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url("fonts/Inter-Black.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Black.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url("fonts/Inter-BlackItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-BlackItalic.woff?v=3.15") format("woff"); +} + +/* ------------------------------------------------------- +Variable font. +Usage: + + html { font-family: 'Inter', sans-serif; } + @supports (font-variation-settings: normal) { + html { font-family: 'Inter var', sans-serif; } + } +*/ +@font-face { + font-family: 'Inter var'; + font-weight: 100 900; + font-display: swap; + font-style: normal; + font-named-instance: 'Regular'; + src: url("fonts/Inter-roman.var.woff2?v=3.15") format("woff2"); +} +@font-face { + font-family: 'Inter var'; + font-weight: 100 900; + font-display: swap; + font-style: italic; + font-named-instance: 'Italic'; + src: url("fonts/Inter-italic.var.woff2?v=3.15") format("woff2"); +} + + +/* -------------------------------------------------------------------------- +[EXPERIMENTAL] Multi-axis, single variable font. + +Slant axis is not yet widely supported (as of February 2019) and thus this +multi-axis single variable font is opt-in rather than the default. + +When using this, you will probably need to set font-variation-settings +explicitly, e.g. + + * { font-variation-settings: "slnt" 0deg } + .italic { font-variation-settings: "slnt" 10deg } + +*/ +@font-face { + font-family: 'Inter var experimental'; + font-weight: 100 900; + font-display: swap; + font-style: oblique 0deg 10deg; + src: url("fonts/Inter.var.woff2?v=3.15") format("woff2"); +} diff --git a/VisualPinball.Unity/Documentation~/template/vpe/token.json b/VisualPinball.Unity/Documentation~/template/vpe/token.json new file mode 100644 index 000000000..310ea224e --- /dev/null +++ b/VisualPinball.Unity/Documentation~/template/vpe/token.json @@ -0,0 +1,3 @@ +{ + "improveThisDoc": "Improve this Doc" +} From 06766c104194686e8ab48ffb855958bc07ecf90d Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 21 Oct 2023 22:36:50 +0200 Subject: [PATCH 123/159] doc: Color left bar and more layout fixes. --- .../template/vpe/layout/_master.tmpl | 4 +-- .../template/vpe/public/main.css | 29 +++++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl b/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl index f29202736..5fd021ba4 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl +++ b/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl @@ -116,7 +116,7 @@
-
+
{{!body}} diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css index a8aa64b48..052aabb67 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -1,9 +1,4 @@ -html, -body { - font-family: Inter, 'Segoe UI', Tahoma, Helvetica, sans-serif; - font-size: 100%; -} - +/* layout */ .navbar-github { order: 100; margin-left: 10px; @@ -13,6 +8,28 @@ body { fill: #ccc; } +body > main { + padding-top: 0; +} + +article { + margin-top: 20px; +} + +main > .toc-offcanvas { + background-color: #efefef; + padding: 15px; + top: calc(35px + 1.6rem) !important; +} + +/* fonts */ +html, +body { + font-family: Inter, 'Segoe UI', Tahoma, Helvetica, sans-serif; + font-size: 100%; +} + + h1, h2 { font-weight: bold; } From f4cf1f610c94db84dd1f0761836978833d3d48c4 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 21 Oct 2023 23:10:57 +0200 Subject: [PATCH 124/159] doc: Fix MPF links. --- .../creators-guide/editor/lamp-manager.md | 2 +- .../creators-guide/editor/wire-manager.md | 2 +- .../creators-guide/manual/mechanisms/light-groups.md | 4 ++-- .../creators-guide/manual/mechanisms/troughs.md | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/VisualPinball.Unity/Documentation~/creators-guide/editor/lamp-manager.md b/VisualPinball.Unity/Documentation~/creators-guide/editor/lamp-manager.md index cc19ff34e..7bfb09ef5 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/editor/lamp-manager.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/editor/lamp-manager.md @@ -20,7 +20,7 @@ To link each of the playfield lamps to the gamelogic engine and configure how th Physical machines have many different implementations when it comes to lighting. The vast majority of solid state machines from the 1970s until the early 2010s used a **lamp matrix**, where lamps were addressed by row/column, and each individual lamp could only be fully on or off. Historically, incandescent light bulbs were used, which resulted in a brief warm-up period until they reached full brightness (and a cool-down period when turned off). To simulate this, VPE adopted the fade-in and fade-out properties for lights from Visual Pinball. -Later machines used single colored **LEDs** that were each directly connected to a controller board (see also: [Lights vs LEDs](https://docs.missionpinball.org/en/latest/mechs/lights/lights_versus_leds.html)). Unlike matrix lamps, the intensity of LEDs could be finely controlled by the game software. +Later machines used single colored **LEDs** that were each directly connected to a controller board (see also: [Lights vs LEDs](https://missionpinball.org/mechs/lights/lights_versus_leds/)). Unlike matrix lamps, the intensity of LEDs could be finely controlled by the game software. More recently, games started using **RGB-LEDs** that can change color as well as brightness during gameplay. In VPE, these can be handled in two different ways: - As three single connections from the gamelogic engine, one for each color channel (this is what PinMAME provides, for example.) diff --git a/VisualPinball.Unity/Documentation~/creators-guide/editor/wire-manager.md b/VisualPinball.Unity/Documentation~/creators-guide/editor/wire-manager.md index dd7a4f246..f226ed7af 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/editor/wire-manager.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/editor/wire-manager.md @@ -71,7 +71,7 @@ However, by design, there are two caveats: > [!note] -> [MPF](xref:mpf_index) has a similar feature called [Hardware Rules](https://docs.missionpinball.org/en/dev/hardware/hw_rules.html#the-solution-hardware-rules). This is the preferred way, because the gamelogic engine explicitly notifies VPE about which wires to add and remove during gameplay. +> [MPF](xref:mpf_index) has a similar feature called [Hardware Rules](https://missionpinball.org/hardware/hw_rules/#the-solution-hardware-rules). This is the preferred way, because the gamelogic engine explicitly notifies VPE about which wires to add and remove during gameplay. > > However, other gamelogic engines like PinMAME don't have this feature, that's why VPE comes with the *dynamic wire* feature that guesses when wire is active and when not. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/light-groups.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/light-groups.md index 9dffbf031..1312452bf 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/light-groups.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/light-groups.md @@ -6,7 +6,7 @@ description: VPE can group and address multiple lights at once. # Light Groups -Sometimes, a game addresses multiple physical lights as one logical lamp, i.e. all lights are always toggled or faded at the same time. Typical use cases are [GI strips](https://docs.missionpinball.org/en/latest/mechs/lights/gis.html). Instead of creating a link in the [Lamp Manager](xref:lamp_manager) for each light separately, VPE ships with a component called *Lamp Group*. +Sometimes, a game addresses multiple physical lights as one logical lamp, i.e. all lights are always toggled or faded at the same time. Typical use cases are [GI strips](https://missionpinball.org/mechs/lights/gis/). Instead of creating a link in the [Lamp Manager](xref:lamp_manager) for each light separately, VPE ships with a component called *Lamp Group*. A light group is a component you can add to any GameObject. It's recommended to make it parent of the light objects it contains, but you can also keep it outside of the lights hierarchy, since it explicitly references the lights it contains. @@ -34,4 +34,4 @@ Simply clears the list. When working with lights, the GameObject with the actual light source is nested within the main object. This can make adjusting light settings for multiple lights tedious, since you have to drill into each parent in order to select the source. -This button selects all the source GameObjects for the lights in the light group. \ No newline at end of file +This button selects all the source GameObjects for the lights in the light group. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/troughs.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/troughs.md index c2b285dba..3d9de9d4b 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/troughs.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/troughs.md @@ -46,7 +46,7 @@ In this section we'll again link to the excellent MPF documentation explaining e -[Modern troughs with mechanical switches](https://docs.missionpinball.org/en/latest/mechs/troughs/#option-2-modern-trough-with-mechanical-switches) are covered by this type. +[Modern troughs with mechanical switches](https://missionpinball.org/mechs/troughs/#option-2-modern-trough-with-mechanical-switches) are covered by this type. The ball drains from the playfield directly into the ball stack, and every ball slot has an associated switch. When a ball gets ejected, the remaining balls move down simultaneously to the next position. During that movement, their switches get first opened and then closed again when they reach the next position. The time of this movement is defined by *Roll Time*. @@ -56,7 +56,7 @@ The ball drains from the playfield directly into the ball stack, and every ball -[Modern troughs with optical switches](https://docs.missionpinball.org/en/latest/mechs/troughs/#option-1-modern-trough-with-opto-sensors) work similar similar to their mechanical counterparts. However there are two differences: +[Modern troughs with optical switches](https://missionpinball.org/mechs/troughs/#option-1-modern-trough-with-opto-sensors) work similar similar to their mechanical counterparts. However there are two differences: 1. Opto switches have the inverse value of mechanical switches. That means per default, an opto switch is *closed*, and when a ball rolls through, it opens. It's kind of logical, because the ball *blocks* the beam of light thus *opening* the circuit, while a mechanical switch gets *closed* by the ball's weight. 2. Timings are different. When a ball approaches an opto switch, the switch gets triggered as soon as the ball's *front* hits the beam, while a mechanical switch gets triggered when the ball's *center* is over it. This results in very short closing times when the ball stack moves to the next position after a ball eject. @@ -72,7 +72,7 @@ We call this closing time the *transition time* - it's the time during stack tra -[Troughs of this type](https://docs.missionpinball.org/en/latest/mechs/troughs/#option-3-older-style-with-two-coils-and-switches-for-each-ball) can be found in older machines from the 80s and early 90s. They consist of two parts: +[Troughs of this type](https://missionpinball.org/mechs/troughs/#option-3-older-style-with-two-coils-and-switches-for-each-ball) can be found in older machines from the 80s and early 90s. They consist of two parts: 1. A drain, the ball rolls into when leaving the playfield 2. A ball stack, where the out of play balls are held. @@ -85,7 +85,7 @@ In terms of switches, they still include a switch per ball in the stack, but als -A trough can also have [only one switch](https://docs.missionpinball.org/en/latest/mechs/troughs/#option-4-older-style-with-two-coils-and-only-one-ball-switch) in the ball stack. +A trough can also have [only one switch](https://missionpinball.org/mechs/troughs/#option-4-older-style-with-two-coils-and-only-one-ball-switch) in the ball stack. Instead of a *Switch Count* like the previous types, you select a *Switch Position*, which is the position in the ball stack at which the ball farthest away from the eject coil sits. @@ -95,7 +95,7 @@ Instead of a *Switch Count* like the previous types, you select a *Switch Positi -A single ball trough may work [with](https://docs.missionpinball.org/en/latest/mechs/troughs/#option-5-classic-single-ball-single-coil) or [without](https://docs.missionpinball.org/en/latest/mechs/troughs/#option-6-classic-single-ball-single-coil-no-shooter-lane) a shooter lane. The principle is simple: After draining, the ball is kept on the drain coil, which ejects the ball either directly into the plunger lane or back onto the playfield. +A single ball trough may work [with](https://missionpinball.org/mechs/troughs/#option-5-classic-single-ball-single-coil) or [without](https://missionpinball.org/mechs/troughs/#option-6-classic-single-ball-single-coil-no-shooter-lane) a shooter lane. The principle is simple: After draining, the ball is kept on the drain coil, which ejects the ball either directly into the plunger lane or back onto the playfield. *The animation shows single ball trough that ejects a ball and drains it a few seconds later.* From bd28e5762b671b0b2377dda56b4aaecde7959d6b Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Oct 2023 01:30:16 +0200 Subject: [PATCH 125/159] doc: Add landing page art, add Zephyr theme with fixes. --- .../Documentation~/creators-guide/toc.yml | 38 +- .../creators-guide/tutorials/index.md | 1 + VisualPinball.Unity/Documentation~/index.md | 152 +- .../Documentation~/plugins/index.md | 2 +- .../template/vpe/public/fonts.css | 201 + .../template/vpe/public/main.css | 316 +- .../template/vpe/public/zephyr.css | 12282 ++++++++++++++++ .../Documentation~/template/vpe/token.json | 2 +- 8 files changed, 12752 insertions(+), 242 deletions(-) create mode 100644 VisualPinball.Unity/Documentation~/template/vpe/public/fonts.css create mode 100644 VisualPinball.Unity/Documentation~/template/vpe/public/zephyr.css diff --git a/VisualPinball.Unity/Documentation~/creators-guide/toc.yml b/VisualPinball.Unity/Documentation~/creators-guide/toc.yml index 9fa539b1e..b6d1f7c04 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/toc.yml +++ b/VisualPinball.Unity/Documentation~/creators-guide/toc.yml @@ -37,50 +37,50 @@ href: tutorials/index.md items: - name: Create a Playfield - href: xref:tutorial_playfield + uid: tutorial_playfield items: - name: Albedo Texture and Masks - href: xref:tutorial_playfield_1 + uid: tutorial_playfield_1 - name: Playfield Mesh - href: xref:tutorial_playfield_2 + uid: tutorial_playfield_2 - name: Texturing - href: xref:tutorial_playfield_3 + uid: tutorial_playfield_3 - name: Texturing (details) - href: xref:tutorial_playfield_3b + uid: tutorial_playfield_3b - name: Import Into Unity - href: xref:tutorial_playfield_4 + uid: tutorial_playfield_4 - name: Create Realistic Looking Plastics - href: xref:tutorial_plastics + uid: tutorial_plastics items: - name: Prepare Artwork - href: xref:tutorial_plastics_1 + uid: tutorial_plastics_1 - name: Create Mesh - href: xref:tutorial_plastics_2 + uid: tutorial_plastics_2 - name: UV-Map Mesh - href: xref:tutorial_plastics_3 + uid: tutorial_plastics_3 - name: Import Into Unity - href: xref:tutorial_plastics_4 + uid: tutorial_plastics_4 - name: Create a Backglass - href: xref:tutorial_backglass + uid: tutorial_backglass items: - name: Prepare Artwork - href: xref:tutorial_backglass_1 + uid: tutorial_backglass_1 - name: Create Mesh - href: xref:tutorial_backglass_2 + uid: tutorial_backglass_2 - name: Import into Unity - href: xref:tutorial_backglass_3 + uid: tutorial_backglass_3 - name: Make a 3D Scan Game-Ready - href: xref:tutorial_3d_scan + uid: tutorial_3d_scan items: - name: Clean Up the Mesh - href: xref:tutorial_3d_scan_1 + uid: tutorial_3d_scan_1 - name: Retopologize - href: xref:tutorial_3d_scan_2 + uid: tutorial_3d_scan_2 - name: Bake Texture Maps - href: xref:tutorial_3d_scan_3 + uid: tutorial_3d_scan_3 - name: Manual href: manual/manual.md diff --git a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/index.md b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/index.md index c88b98532..9d80566cb 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/index.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/index.md @@ -9,3 +9,4 @@ description: Visual Pinball for Unity - Tutorials - [Create a Playfield](xref:tutorial_playfield) - [Create Realistic Looking Plastics](xref:tutorial_plastics) - [Create a Backglass](xref:tutorial_backglass) +- [Make a 3D Scan Game-Ready](xref:tutorial_3d_scan) diff --git a/VisualPinball.Unity/Documentation~/index.md b/VisualPinball.Unity/Documentation~/index.md index 53b8921a5..c00db95a4 100644 --- a/VisualPinball.Unity/Documentation~/index.md +++ b/VisualPinball.Unity/Documentation~/index.md @@ -2,12 +2,162 @@ title: Welcome description: Visual Pinball for Unity - Documentation, Guides and Tutorials. layout: landing +is_full: true ---
Welcome to the documentation of the - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VISUAL PINBALL ENGINE + + [Start here with the creator's guide](xref:vpe-overview). diff --git a/VisualPinball.Unity/Documentation~/plugins/index.md b/VisualPinball.Unity/Documentation~/plugins/index.md index 996f2ce04..7c55af80f 100644 --- a/VisualPinball.Unity/Documentation~/plugins/index.md +++ b/VisualPinball.Unity/Documentation~/plugins/index.md @@ -14,7 +14,7 @@ VPE has a plug-in system that allows other software to integrate with it. Plugin ## [Visual Scripting](xref:uvs_index) -For original games or EM machines, we recommend using our visual scripting package which extends [Unity's visual scripting](https://unity.com/products/unity-visual-scripting). +For original games or EM machines, we recommend using our visual scripting package which extends [Unity's Visual Scripting](https://unity.com/products/unity-visual-scripting). ## [Mission Pinball Framework](xref:mpf_index) diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/fonts.css b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts.css new file mode 100644 index 000000000..c0ee3259e --- /dev/null +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/fonts.css @@ -0,0 +1,201 @@ + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 100; + font-display: swap; + src: url("fonts/Inter-Thin.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Thin.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 100; + font-display: swap; + src: url("fonts/Inter-ThinItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-ThinItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 200; + font-display: swap; + src: url("fonts/Inter-ExtraLight.woff2?v=3.15") format("woff2"), + url("fonts/Inter-ExtraLight.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 200; + font-display: swap; + src: url("fonts/Inter-ExtraLightItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-ExtraLightItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 300; + font-display: swap; + src: url("fonts/Inter-Light.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Light.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 300; + font-display: swap; + src: url("fonts/Inter-LightItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-LightItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url("fonts/Inter-Regular.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Regular.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 400; + font-display: swap; + src: url("fonts/Inter-Italic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Italic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 500; + font-display: swap; + src: url("fonts/Inter-Medium.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Medium.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 500; + font-display: swap; + src: url("fonts/Inter-MediumItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-MediumItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url("fonts/Inter-SemiBold.woff2?v=3.15") format("woff2"), + url("fonts/Inter-SemiBold.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 600; + font-display: swap; + src: url("fonts/Inter-SemiBoldItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-SemiBoldItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url("fonts/Inter-Bold.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Bold.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 700; + font-display: swap; + src: url("fonts/Inter-BoldItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-BoldItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 800; + font-display: swap; + src: url("fonts/Inter-ExtraBold.woff2?v=3.15") format("woff2"), + url("fonts/Inter-ExtraBold.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 800; + font-display: swap; + src: url("fonts/Inter-ExtraBoldItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-ExtraBoldItalic.woff?v=3.15") format("woff"); +} + +@font-face { + font-family: 'Inter'; + font-style: normal; + font-weight: 900; + font-display: swap; + src: url("fonts/Inter-Black.woff2?v=3.15") format("woff2"), + url("fonts/Inter-Black.woff?v=3.15") format("woff"); +} +@font-face { + font-family: 'Inter'; + font-style: italic; + font-weight: 900; + font-display: swap; + src: url("fonts/Inter-BlackItalic.woff2?v=3.15") format("woff2"), + url("fonts/Inter-BlackItalic.woff?v=3.15") format("woff"); +} + +/* ------------------------------------------------------- +Variable font. +Usage: + + html { font-family: 'Inter', sans-serif; } + @supports (font-variation-settings: normal) { + html { font-family: 'Inter var', sans-serif; } + } +*/ +@font-face { + font-family: 'Inter var'; + font-weight: 100 900; + font-display: swap; + font-style: normal; + font-named-instance: 'Regular'; + src: url("fonts/Inter-roman.var.woff2?v=3.15") format("woff2"); +} +@font-face { + font-family: 'Inter var'; + font-weight: 100 900; + font-display: swap; + font-style: italic; + font-named-instance: 'Italic'; + src: url("fonts/Inter-italic.var.woff2?v=3.15") format("woff2"); +} + + +/* -------------------------------------------------------------------------- +[EXPERIMENTAL] Multi-axis, single variable font. + +Slant axis is not yet widely supported (as of February 2019) and thus this +multi-axis single variable font is opt-in rather than the default. + +When using this, you will probably need to set font-variation-settings +explicitly, e.g. + + * { font-variation-settings: "slnt" 0deg } + .italic { font-variation-settings: "slnt" 10deg } + +*/ +@font-face { + font-family: 'Inter var experimental'; + font-weight: 100 900; + font-display: swap; + font-style: oblique 0deg 10deg; + src: url("fonts/Inter.var.woff2?v=3.15") format("woff2"); +} diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css index 052aabb67..f4ce4db98 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -1,43 +1,120 @@ +@import url("fonts.css"); +@import url("zephyr.css"); + /* layout */ -.navbar-github { +.navbar-github { /* align github link to the right */ order: 100; margin-left: 10px; margin-top: 4px; } -.navbar-github > svg { +.navbar-github > svg { /* github logo color */ fill: #ccc; } -body > main { - padding-top: 0; +body[data-layout=landing]>main { /* landing page full width */ + display: block; +} +#vpe-halftone { /* landing page logo width */ + max-width: 720px; + display: block; +} + +:root, +[data-bs-theme=light] { + --bs-font-sans-serif: Inter, 'Segoe UI', Tahoma, Helvetica, sans-serif; + --bs-body-font-family: var(--bs-font-sans-serif); + --bs-link-color-rgb: 214, 99, 22; + --bs-link-hover-color-rgb: 183, 74, 0; + --vpe-body-bg-secondary: #f3f3f3; + --vpe-link-secondary: #00000080; + --vpe-link-secondary-hover: #000000aa; +} +[data-bs-theme=dark] { + --bs-link-color-rgb: 236, 132, 61; + --vpe-body-bg-secondary: #292e33; + --vpe-link-secondary: #ffffff80; + --vpe-link-secondary-hover: #ffffffaa; +} + +[data-bs-theme=dark] header { /* header slightly lighter in dark mode */ + background-color: var(--vpe-body-bg-secondary) !important; +} + +/* don't underline links */ +a { + text-decoration: none !important; } -article { - margin-top: 20px; +/* zephyr fixes */ +.btn-outline-secondary { + color: var(--bs-secondary-color) !important; +} +[data-bs-theme=dark] .btn-outline-secondary:hover { + color: var(--bs-body-bg) !important; +} +.link-secondary { + color: var(--vpe-link-secondary) !important; +} +.link-secondary:hover { + color: var(--vpe-link-secondary-hover) !important; +} +#search-results > .sr-items .sr-item > .item-href { + color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); } -main > .toc-offcanvas { - background-color: #efefef; - padding: 15px; - top: calc(35px + 1.6rem) !important; + /* landing logo colors */ +svg .cls-1 { /* visual pinball engine */ + fill: var(--bs-body-color); + font-family: Asgalt-Regular, Asgalt; + font-size: 34.4px; + letter-spacing: .19em; +} +svg .cls-2, .cls-3, .cls-4 { /* outer */ + stroke-width: 0px; + fill: var(--bs-body-bg) +} +svg .cls-3 { /* logo */ + fill: var(--bs-body-color); +} +svg .cls-4 { + fill: var(--vpe-body-bg-secondary); } -/* fonts */ -html, -body { - font-family: Inter, 'Segoe UI', Tahoma, Helvetica, sans-serif; - font-size: 100%; +.border-top:not(.next-article) { /* footer background color */ + background-color: var(--vpe-body-bg-secondary); } +/*body > main {*/ +/* padding-top: 0;*/ +/*}*/ + +/*article {*/ +/* margin-top: 20px;*/ +/*}*/ + +/*main > .toc-offcanvas {*/ +/* background-color: #efefef;*/ +/* padding: 15px;*/ +/* top: calc(35px + 1.6rem) !important;*/ +/* max-height: calc(100vh - 35px - 1.6rem) !important;*/ +/*}*/ + +/*!* fonts *!*/ +/*html,*/ +/*body {*/ +/* font-family: Inter, 'Segoe UI', Tahoma, Helvetica, sans-serif;*/ +/* font-size: 100%;*/ +/*}*/ + h1, h2 { font-weight: bold; } -.affix h5 { /* "In this article" */ - font-weight: 600; - letter-spacing: normal !important; -} +/*.affix h5 { !* "In this article" *!*/ +/* font-weight: 600;*/ +/* letter-spacing: normal !important;*/ +/*}*/ /*header .btn:hover {*/ /* background-color: #fff;*/ @@ -85,204 +162,3 @@ h1, h2 { /*.table-striped > tbody > tr:nth-of-type(odd) {*/ /* background-color: rgba(1,1,1,0.03)*/ /*}*/ - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 100; - font-display: swap; - src: url("fonts/Inter-Thin.woff2?v=3.15") format("woff2"), - url("fonts/Inter-Thin.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 100; - font-display: swap; - src: url("fonts/Inter-ThinItalic.woff2?v=3.15") format("woff2"), - url("fonts/Inter-ThinItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 200; - font-display: swap; - src: url("fonts/Inter-ExtraLight.woff2?v=3.15") format("woff2"), - url("fonts/Inter-ExtraLight.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 200; - font-display: swap; - src: url("fonts/Inter-ExtraLightItalic.woff2?v=3.15") format("woff2"), - url("fonts/Inter-ExtraLightItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: url("fonts/Inter-Light.woff2?v=3.15") format("woff2"), - url("fonts/Inter-Light.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 300; - font-display: swap; - src: url("fonts/Inter-LightItalic.woff2?v=3.15") format("woff2"), - url("fonts/Inter-LightItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 400; - font-display: swap; - src: url("fonts/Inter-Regular.woff2?v=3.15") format("woff2"), - url("fonts/Inter-Regular.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 400; - font-display: swap; - src: url("fonts/Inter-Italic.woff2?v=3.15") format("woff2"), - url("fonts/Inter-Italic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 500; - font-display: swap; - src: url("fonts/Inter-Medium.woff2?v=3.15") format("woff2"), - url("fonts/Inter-Medium.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 500; - font-display: swap; - src: url("fonts/Inter-MediumItalic.woff2?v=3.15") format("woff2"), - url("fonts/Inter-MediumItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 600; - font-display: swap; - src: url("fonts/Inter-SemiBold.woff2?v=3.15") format("woff2"), - url("fonts/Inter-SemiBold.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 600; - font-display: swap; - src: url("fonts/Inter-SemiBoldItalic.woff2?v=3.15") format("woff2"), - url("fonts/Inter-SemiBoldItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 700; - font-display: swap; - src: url("fonts/Inter-Bold.woff2?v=3.15") format("woff2"), - url("fonts/Inter-Bold.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 700; - font-display: swap; - src: url("fonts/Inter-BoldItalic.woff2?v=3.15") format("woff2"), - url("fonts/Inter-BoldItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 800; - font-display: swap; - src: url("fonts/Inter-ExtraBold.woff2?v=3.15") format("woff2"), - url("fonts/Inter-ExtraBold.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 800; - font-display: swap; - src: url("fonts/Inter-ExtraBoldItalic.woff2?v=3.15") format("woff2"), - url("fonts/Inter-ExtraBoldItalic.woff?v=3.15") format("woff"); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 900; - font-display: swap; - src: url("fonts/Inter-Black.woff2?v=3.15") format("woff2"), - url("fonts/Inter-Black.woff?v=3.15") format("woff"); -} -@font-face { - font-family: 'Inter'; - font-style: italic; - font-weight: 900; - font-display: swap; - src: url("fonts/Inter-BlackItalic.woff2?v=3.15") format("woff2"), - url("fonts/Inter-BlackItalic.woff?v=3.15") format("woff"); -} - -/* ------------------------------------------------------- -Variable font. -Usage: - - html { font-family: 'Inter', sans-serif; } - @supports (font-variation-settings: normal) { - html { font-family: 'Inter var', sans-serif; } - } -*/ -@font-face { - font-family: 'Inter var'; - font-weight: 100 900; - font-display: swap; - font-style: normal; - font-named-instance: 'Regular'; - src: url("fonts/Inter-roman.var.woff2?v=3.15") format("woff2"); -} -@font-face { - font-family: 'Inter var'; - font-weight: 100 900; - font-display: swap; - font-style: italic; - font-named-instance: 'Italic'; - src: url("fonts/Inter-italic.var.woff2?v=3.15") format("woff2"); -} - - -/* -------------------------------------------------------------------------- -[EXPERIMENTAL] Multi-axis, single variable font. - -Slant axis is not yet widely supported (as of February 2019) and thus this -multi-axis single variable font is opt-in rather than the default. - -When using this, you will probably need to set font-variation-settings -explicitly, e.g. - - * { font-variation-settings: "slnt" 0deg } - .italic { font-variation-settings: "slnt" 10deg } - -*/ -@font-face { - font-family: 'Inter var experimental'; - font-weight: 100 900; - font-display: swap; - font-style: oblique 0deg 10deg; - src: url("fonts/Inter.var.woff2?v=3.15") format("woff2"); -} diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/zephyr.css b/VisualPinball.Unity/Documentation~/template/vpe/public/zephyr.css new file mode 100644 index 000000000..94dc11023 --- /dev/null +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/zephyr.css @@ -0,0 +1,12282 @@ +@charset "UTF-8"; +/*! + * Bootswatch v5.3.2 (https://bootswatch.com) + * Theme: zephyr + * Copyright 2012-2023 Thomas Park + * Licensed under MIT + * Based on Bootstrap +*/ +/*! + * Bootstrap v5.3.2 (https://getbootstrap.com/) + * Copyright 2011-2023 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +:root, +[data-bs-theme=light] { + --bs-blue: #3459e6; + --bs-indigo: #6610f2; + --bs-purple: #6f42c1; + --bs-pink: #d63384; + --bs-red: #da292e; + --bs-orange: #f8765f; + --bs-yellow: #f4bd61; + --bs-green: #2fb380; + --bs-teal: #20c997; + --bs-cyan: #287bb5; + --bs-black: #000; + --bs-white: #fff; + --bs-gray: #6c757d; + --bs-gray-dark: #343a40; + --bs-gray-100: #f8f9fa; + --bs-gray-200: #e9ecef; + --bs-gray-300: #dee2e6; + --bs-gray-400: #ced4da; + --bs-gray-500: #adb5bd; + --bs-gray-600: #6c757d; + --bs-gray-700: #495057; + --bs-gray-800: #343a40; + --bs-gray-900: #212529; + --bs-primary: #3459e6; + --bs-secondary: #fff; + --bs-success: #2fb380; + --bs-info: #287bb5; + --bs-warning: #f4bd61; + --bs-danger: #da292e; + --bs-light: #f8f9fa; + --bs-dark: #212529; + --bs-primary-rgb: 52, 89, 230; + --bs-secondary-rgb: 255, 255, 255; + --bs-success-rgb: 47, 179, 128; + --bs-info-rgb: 40, 123, 181; + --bs-warning-rgb: 244, 189, 97; + --bs-danger-rgb: 218, 41, 46; + --bs-light-rgb: 248, 249, 250; + --bs-dark-rgb: 33, 37, 41; + --bs-primary-text-emphasis: #15245c; + --bs-secondary-text-emphasis: #666666; + --bs-success-text-emphasis: #134833; + --bs-info-text-emphasis: #103148; + --bs-warning-text-emphasis: #624c27; + --bs-danger-text-emphasis: #571012; + --bs-light-text-emphasis: #495057; + --bs-dark-text-emphasis: #495057; + --bs-primary-bg-subtle: #d6defa; + --bs-secondary-bg-subtle: white; + --bs-success-bg-subtle: #d5f0e6; + --bs-info-bg-subtle: #d4e5f0; + --bs-warning-bg-subtle: #fdf2df; + --bs-danger-bg-subtle: #f8d4d5; + --bs-light-bg-subtle: #fcfcfd; + --bs-dark-bg-subtle: #ced4da; + --bs-primary-border-subtle: #aebdf5; + --bs-secondary-border-subtle: white; + --bs-success-border-subtle: #ace1cc; + --bs-info-border-subtle: #a9cae1; + --bs-warning-border-subtle: #fbe5c0; + --bs-danger-border-subtle: #f0a9ab; + --bs-light-border-subtle: #e9ecef; + --bs-dark-border-subtle: #adb5bd; + --bs-white-rgb: 255, 255, 255; + --bs-black-rgb: 0, 0, 0; + --bs-font-sans-serif: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); + --bs-body-font-family: var(--bs-font-sans-serif); + --bs-body-font-size: 1rem; + --bs-body-font-weight: 400; + --bs-body-line-height: 1.5; + --bs-body-color: #495057; + --bs-body-color-rgb: 73, 80, 87; + --bs-body-bg: #fff; + --bs-body-bg-rgb: 255, 255, 255; + --bs-emphasis-color: #000; + --bs-emphasis-color-rgb: 0, 0, 0; + --bs-secondary-color: rgba(73, 80, 87, 0.75); + --bs-secondary-color-rgb: 73, 80, 87; + --bs-secondary-bg: #e9ecef; + --bs-secondary-bg-rgb: 233, 236, 239; + --bs-tertiary-color: rgba(73, 80, 87, 0.5); + --bs-tertiary-color-rgb: 73, 80, 87; + --bs-tertiary-bg: #f8f9fa; + --bs-tertiary-bg-rgb: 248, 249, 250; + --bs-heading-color: var(--bs-primary-color); + --bs-link-color: #3459e6; + --bs-link-color-rgb: 214, 99, 22; + --bs-link-decoration: underline; + --bs-link-hover-color: #2a47b8; + --bs-link-hover-color-rgb: 42, 71, 184; + --bs-code-color: #d63384; + --bs-highlight-color: #495057; + --bs-highlight-bg: #fdf2df; + --bs-border-width: 1px; + --bs-border-style: solid; + --bs-border-color: #dee2e6; + --bs-border-color-translucent: rgba(0, 0, 0, 0.175); + --bs-border-radius: 0.375rem; + --bs-border-radius-sm: 0.25rem; + --bs-border-radius-lg: 0.5rem; + --bs-border-radius-xl: 1rem; + --bs-border-radius-xxl: 2rem; + --bs-border-radius-2xl: var(--bs-border-radius-xxl); + --bs-border-radius-pill: 50rem; + --bs-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); + --bs-box-shadow-lg: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); + --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075); + --bs-focus-ring-width: 0.25rem; + --bs-focus-ring-opacity: 0.25; + --bs-focus-ring-color: rgba(52, 89, 230, 0.25); + --bs-form-valid-color: #2fb380; + --bs-form-valid-border-color: #2fb380; + --bs-form-invalid-color: #da292e; + --bs-form-invalid-border-color: #da292e; +} + +[data-bs-theme=dark] { + color-scheme: dark; + --bs-body-color: #dee2e6; + --bs-body-color-rgb: 222, 226, 230; + --bs-body-bg: #212529; + --bs-body-bg-rgb: 33, 37, 41; + --bs-emphasis-color: #fff; + --bs-emphasis-color-rgb: 255, 255, 255; + --bs-secondary-color: rgba(222, 226, 230, 0.75); + --bs-secondary-color-rgb: 222, 226, 230; + --bs-secondary-bg: #343a40; + --bs-secondary-bg-rgb: 52, 58, 64; + --bs-tertiary-color: rgba(222, 226, 230, 0.5); + --bs-tertiary-color-rgb: 222, 226, 230; + --bs-tertiary-bg: #2b3035; + --bs-tertiary-bg-rgb: 43, 48, 53; + --bs-primary-text-emphasis: #859bf0; + --bs-secondary-text-emphasis: white; + --bs-success-text-emphasis: #82d1b3; + --bs-info-text-emphasis: #7eb0d3; + --bs-warning-text-emphasis: #f8d7a0; + --bs-danger-text-emphasis: #e97f82; + --bs-light-text-emphasis: #f8f9fa; + --bs-dark-text-emphasis: #dee2e6; + --bs-primary-bg-subtle: #0a122e; + --bs-secondary-bg-subtle: #333333; + --bs-success-bg-subtle: #09241a; + --bs-info-bg-subtle: #081924; + --bs-warning-bg-subtle: #312613; + --bs-danger-bg-subtle: #2c0809; + --bs-light-bg-subtle: #343a40; + --bs-dark-bg-subtle: #1a1d20; + --bs-primary-border-subtle: #1f358a; + --bs-secondary-border-subtle: #999999; + --bs-success-border-subtle: #1c6b4d; + --bs-info-border-subtle: #184a6d; + --bs-warning-border-subtle: #92713a; + --bs-danger-border-subtle: #83191c; + --bs-light-border-subtle: #495057; + --bs-dark-border-subtle: #343a40; + --bs-heading-color: inherit; + --bs-link-color: #859bf0; + --bs-link-hover-color: #9daff3; + --bs-link-color-rgb: 133, 155, 240; + --bs-link-hover-color-rgb: 157, 175, 243; + --bs-code-color: #e685b5; + --bs-highlight-color: #dee2e6; + --bs-highlight-bg: #624c27; + --bs-border-color: #495057; + --bs-border-color-translucent: rgba(255, 255, 255, 0.15); + --bs-form-valid-color: #82d1b3; + --bs-form-valid-border-color: #82d1b3; + --bs-form-invalid-color: #e97f82; + --bs-form-invalid-border-color: #e97f82; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +@media (prefers-reduced-motion: no-preference) { + :root { + scroll-behavior: smooth; + } +} + +body { + margin: 0; + font-family: var(--bs-body-font-family); + font-size: var(--bs-body-font-size); + font-weight: var(--bs-body-font-weight); + line-height: var(--bs-body-line-height); + color: var(--bs-body-color); + text-align: var(--bs-body-text-align); + background-color: var(--bs-body-bg); + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +hr { + margin: 1rem 0; + color: inherit; + border: 0; + border-top: var(--bs-border-width) solid; + opacity: 0.25; +} + +h6, .h6, h5, .h5, h4, .h4, h3, .h3, h2, .h2, h1, .h1 { + margin-top: 0; + margin-bottom: 0.5rem; + font-weight: 500; + line-height: 1.2; + color: var(--bs-heading-color); +} + +h1, .h1 { + font-size: calc(1.375rem + 1.5vw); +} +@media (min-width: 1200px) { + h1, .h1 { + font-size: 2.5rem; + } +} + +h2, .h2 { + font-size: calc(1.325rem + 0.9vw); +} +@media (min-width: 1200px) { + h2, .h2 { + font-size: 2rem; + } +} + +h3, .h3 { + font-size: calc(1.3rem + 0.6vw); +} +@media (min-width: 1200px) { + h3, .h3 { + font-size: 1.75rem; + } +} + +h4, .h4 { + font-size: calc(1.275rem + 0.3vw); +} +@media (min-width: 1200px) { + h4, .h4 { + font-size: 1.5rem; + } +} + +h5, .h5 { + font-size: 1.25rem; +} + +h6, .h6 { + font-size: 1rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +abbr[title] { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + -webkit-text-decoration-skip-ink: none; + text-decoration-skip-ink: none; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul { + padding-left: 2rem; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: 700; +} + +dd { + margin-bottom: 0.5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +b, +strong { + font-weight: bolder; +} + +small, .small { + font-size: 0.875em; +} + +mark, .mark { + padding: 0.1875em; + color: var(--bs-highlight-color); + background-color: var(--bs-highlight-bg); +} + +sub, +sup { + position: relative; + font-size: 0.75em; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +a { + color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); + text-decoration: underline; +} +a:hover { + --bs-link-color-rgb: var(--bs-link-hover-color-rgb); +} + +a:not([href]):not([class]), a:not([href]):not([class]):hover { + color: inherit; + text-decoration: none; +} + +pre, +code, +kbd, +samp { + font-family: var(--bs-font-monospace); + font-size: 1em; +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + font-size: 0.875em; +} +pre code { + font-size: inherit; + color: inherit; + word-break: normal; +} + +code { + font-size: 0.875em; + color: var(--bs-code-color); + word-wrap: break-word; +} +a > code { + color: inherit; +} + +kbd { + padding: 0.1875rem 0.375rem; + font-size: 0.875em; + color: var(--bs-body-bg); + background-color: var(--bs-body-color); + border-radius: 0.25rem; +} +kbd kbd { + padding: 0; + font-size: 1em; +} + +figure { + margin: 0 0 1rem; +} + +img, +svg { + vertical-align: middle; +} + +table { + caption-side: bottom; + border-collapse: collapse; +} + +caption { + padding-top: 1rem; + padding-bottom: 1rem; + color: var(--bs-secondary-color); + text-align: left; +} + +th { + font-weight: 500; + text-align: inherit; + text-align: -webkit-match-parent; +} + +thead, +tbody, +tfoot, +tr, +td, +th { + border-color: inherit; + border-style: solid; + border-width: 0; +} + +label { + display: inline-block; +} + +button { + border-radius: 0; +} + +button:focus:not(:focus-visible) { + outline: 0; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +select { + text-transform: none; +} + +[role=button] { + cursor: pointer; +} + +select { + word-wrap: normal; +} +select:disabled { + opacity: 1; +} + +[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { + display: none !important; +} + +button, +[type=button], +[type=reset], +[type=submit] { + -webkit-appearance: button; +} +button:not(:disabled), +[type=button]:not(:disabled), +[type=reset]:not(:disabled), +[type=submit]:not(:disabled) { + cursor: pointer; +} + +::-moz-focus-inner { + padding: 0; + border-style: none; +} + +textarea { + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + float: left; + width: 100%; + padding: 0; + margin-bottom: 0.5rem; + font-size: calc(1.275rem + 0.3vw); + line-height: inherit; +} +@media (min-width: 1200px) { + legend { + font-size: 1.5rem; + } +} +legend + * { + clear: left; +} + +::-webkit-datetime-edit-fields-wrapper, +::-webkit-datetime-edit-text, +::-webkit-datetime-edit-minute, +::-webkit-datetime-edit-hour-field, +::-webkit-datetime-edit-day-field, +::-webkit-datetime-edit-month-field, +::-webkit-datetime-edit-year-field { + padding: 0; +} + +::-webkit-inner-spin-button { + height: auto; +} + +[type=search] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +/* rtl:raw: +[type="tel"], +[type="url"], +[type="email"], +[type="number"] { + direction: ltr; +} +*/ +::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-color-swatch-wrapper { + padding: 0; +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button; +} + +::file-selector-button { + font: inherit; + -webkit-appearance: button; +} + +output { + display: inline-block; +} + +iframe { + border: 0; +} + +summary { + display: list-item; + cursor: pointer; +} + +progress { + vertical-align: baseline; +} + +[hidden] { + display: none !important; +} + +.lead { + font-size: 1.25rem; + font-weight: 300; +} + +.display-1 { + font-size: calc(1.625rem + 4.5vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-1 { + font-size: 5rem; + } +} + +.display-2 { + font-size: calc(1.575rem + 3.9vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-2 { + font-size: 4.5rem; + } +} + +.display-3 { + font-size: calc(1.525rem + 3.3vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-3 { + font-size: 4rem; + } +} + +.display-4 { + font-size: calc(1.475rem + 2.7vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-4 { + font-size: 3.5rem; + } +} + +.display-5 { + font-size: calc(1.425rem + 2.1vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-5 { + font-size: 3rem; + } +} + +.display-6 { + font-size: calc(1.375rem + 1.5vw); + font-weight: 300; + line-height: 1.2; +} +@media (min-width: 1200px) { + .display-6 { + font-size: 2.5rem; + } +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-inline-item { + display: inline-block; +} +.list-inline-item:not(:last-child) { + margin-right: 0.5rem; +} + +.initialism { + font-size: 0.875em; + text-transform: uppercase; +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem; +} +.blockquote > :last-child { + margin-bottom: 0; +} + +.blockquote-footer { + margin-top: -1rem; + margin-bottom: 1rem; + font-size: 0.875em; + color: #6c757d; +} +.blockquote-footer::before { + content: "— "; +} + +.img-fluid { + max-width: 100%; + height: auto; +} + +.img-thumbnail { + padding: 0.25rem; + background-color: var(--bs-body-bg); + border: var(--bs-border-width) solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + box-shadow: var(--bs-box-shadow-sm); + max-width: 100%; + height: auto; +} + +.figure { + display: inline-block; +} + +.figure-img { + margin-bottom: 0.5rem; + line-height: 1; +} + +.figure-caption { + font-size: 0.875em; + color: var(--bs-secondary-color); +} + +.container, +.container-fluid, +.container-xxl, +.container-xl, +.container-lg, +.container-md, +.container-sm { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + width: 100%; + padding-right: calc(var(--bs-gutter-x) * 0.5); + padding-left: calc(var(--bs-gutter-x) * 0.5); + margin-right: auto; + margin-left: auto; +} + +@media (min-width: 576px) { + .container-sm, .container { + max-width: 540px; + } +} +@media (min-width: 768px) { + .container-md, .container-sm, .container { + max-width: 720px; + } +} +@media (min-width: 992px) { + .container-lg, .container-md, .container-sm, .container { + max-width: 960px; + } +} +@media (min-width: 1200px) { + .container-xl, .container-lg, .container-md, .container-sm, .container { + max-width: 1140px; + } +} +@media (min-width: 1400px) { + .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container { + max-width: 1320px; + } +} +:root { + --bs-breakpoint-xs: 0; + --bs-breakpoint-sm: 576px; + --bs-breakpoint-md: 768px; + --bs-breakpoint-lg: 992px; + --bs-breakpoint-xl: 1200px; + --bs-breakpoint-xxl: 1400px; +} + +.row { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(-1 * var(--bs-gutter-y)); + margin-right: calc(-0.5 * var(--bs-gutter-x)); + margin-left: calc(-0.5 * var(--bs-gutter-x)); +} +.row > * { + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--bs-gutter-x) * 0.5); + padding-left: calc(var(--bs-gutter-x) * 0.5); + margin-top: var(--bs-gutter-y); +} + +.col { + flex: 1 0 0%; +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto; +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100%; +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50%; +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.33333333%; +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25%; +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20%; +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.66666667%; +} + +.col-auto { + flex: 0 0 auto; + width: auto; +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333%; +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667%; +} + +.col-3 { + flex: 0 0 auto; + width: 25%; +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333%; +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667%; +} + +.col-6 { + flex: 0 0 auto; + width: 50%; +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333%; +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667%; +} + +.col-9 { + flex: 0 0 auto; + width: 75%; +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333%; +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667%; +} + +.col-12 { + flex: 0 0 auto; + width: 100%; +} + +.offset-1 { + margin-left: 8.33333333%; +} + +.offset-2 { + margin-left: 16.66666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.33333333%; +} + +.offset-5 { + margin-left: 41.66666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.33333333%; +} + +.offset-8 { + margin-left: 66.66666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.33333333%; +} + +.offset-11 { + margin-left: 91.66666667%; +} + +.g-0, +.gx-0 { + --bs-gutter-x: 0; +} + +.g-0, +.gy-0 { + --bs-gutter-y: 0; +} + +.g-1, +.gx-1 { + --bs-gutter-x: 0.25rem; +} + +.g-1, +.gy-1 { + --bs-gutter-y: 0.25rem; +} + +.g-2, +.gx-2 { + --bs-gutter-x: 0.5rem; +} + +.g-2, +.gy-2 { + --bs-gutter-y: 0.5rem; +} + +.g-3, +.gx-3 { + --bs-gutter-x: 1rem; +} + +.g-3, +.gy-3 { + --bs-gutter-y: 1rem; +} + +.g-4, +.gx-4 { + --bs-gutter-x: 1.5rem; +} + +.g-4, +.gy-4 { + --bs-gutter-y: 1.5rem; +} + +.g-5, +.gx-5 { + --bs-gutter-x: 3rem; +} + +.g-5, +.gy-5 { + --bs-gutter-y: 3rem; +} + +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0%; + } + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-sm-auto { + flex: 0 0 auto; + width: auto; + } + .col-sm-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-sm-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-sm-3 { + flex: 0 0 auto; + width: 25%; + } + .col-sm-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-sm-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-sm-6 { + flex: 0 0 auto; + width: 50%; + } + .col-sm-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-sm-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-sm-9 { + flex: 0 0 auto; + width: 75%; + } + .col-sm-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-sm-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-sm-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-sm-0 { + margin-left: 0; + } + .offset-sm-1 { + margin-left: 8.33333333%; + } + .offset-sm-2 { + margin-left: 16.66666667%; + } + .offset-sm-3 { + margin-left: 25%; + } + .offset-sm-4 { + margin-left: 33.33333333%; + } + .offset-sm-5 { + margin-left: 41.66666667%; + } + .offset-sm-6 { + margin-left: 50%; + } + .offset-sm-7 { + margin-left: 58.33333333%; + } + .offset-sm-8 { + margin-left: 66.66666667%; + } + .offset-sm-9 { + margin-left: 75%; + } + .offset-sm-10 { + margin-left: 83.33333333%; + } + .offset-sm-11 { + margin-left: 91.66666667%; + } + .g-sm-0, + .gx-sm-0 { + --bs-gutter-x: 0; + } + .g-sm-0, + .gy-sm-0 { + --bs-gutter-y: 0; + } + .g-sm-1, + .gx-sm-1 { + --bs-gutter-x: 0.25rem; + } + .g-sm-1, + .gy-sm-1 { + --bs-gutter-y: 0.25rem; + } + .g-sm-2, + .gx-sm-2 { + --bs-gutter-x: 0.5rem; + } + .g-sm-2, + .gy-sm-2 { + --bs-gutter-y: 0.5rem; + } + .g-sm-3, + .gx-sm-3 { + --bs-gutter-x: 1rem; + } + .g-sm-3, + .gy-sm-3 { + --bs-gutter-y: 1rem; + } + .g-sm-4, + .gx-sm-4 { + --bs-gutter-x: 1.5rem; + } + .g-sm-4, + .gy-sm-4 { + --bs-gutter-y: 1.5rem; + } + .g-sm-5, + .gx-sm-5 { + --bs-gutter-x: 3rem; + } + .g-sm-5, + .gy-sm-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 768px) { + .col-md { + flex: 1 0 0%; + } + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-md-auto { + flex: 0 0 auto; + width: auto; + } + .col-md-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-md-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-md-3 { + flex: 0 0 auto; + width: 25%; + } + .col-md-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-md-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-md-6 { + flex: 0 0 auto; + width: 50%; + } + .col-md-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-md-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-md-9 { + flex: 0 0 auto; + width: 75%; + } + .col-md-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-md-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-md-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-md-0 { + margin-left: 0; + } + .offset-md-1 { + margin-left: 8.33333333%; + } + .offset-md-2 { + margin-left: 16.66666667%; + } + .offset-md-3 { + margin-left: 25%; + } + .offset-md-4 { + margin-left: 33.33333333%; + } + .offset-md-5 { + margin-left: 41.66666667%; + } + .offset-md-6 { + margin-left: 50%; + } + .offset-md-7 { + margin-left: 58.33333333%; + } + .offset-md-8 { + margin-left: 66.66666667%; + } + .offset-md-9 { + margin-left: 75%; + } + .offset-md-10 { + margin-left: 83.33333333%; + } + .offset-md-11 { + margin-left: 91.66666667%; + } + .g-md-0, + .gx-md-0 { + --bs-gutter-x: 0; + } + .g-md-0, + .gy-md-0 { + --bs-gutter-y: 0; + } + .g-md-1, + .gx-md-1 { + --bs-gutter-x: 0.25rem; + } + .g-md-1, + .gy-md-1 { + --bs-gutter-y: 0.25rem; + } + .g-md-2, + .gx-md-2 { + --bs-gutter-x: 0.5rem; + } + .g-md-2, + .gy-md-2 { + --bs-gutter-y: 0.5rem; + } + .g-md-3, + .gx-md-3 { + --bs-gutter-x: 1rem; + } + .g-md-3, + .gy-md-3 { + --bs-gutter-y: 1rem; + } + .g-md-4, + .gx-md-4 { + --bs-gutter-x: 1.5rem; + } + .g-md-4, + .gy-md-4 { + --bs-gutter-y: 1.5rem; + } + .g-md-5, + .gx-md-5 { + --bs-gutter-x: 3rem; + } + .g-md-5, + .gy-md-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0%; + } + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-lg-auto { + flex: 0 0 auto; + width: auto; + } + .col-lg-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-lg-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-lg-3 { + flex: 0 0 auto; + width: 25%; + } + .col-lg-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-lg-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-lg-6 { + flex: 0 0 auto; + width: 50%; + } + .col-lg-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-lg-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-lg-9 { + flex: 0 0 auto; + width: 75%; + } + .col-lg-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-lg-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-lg-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-lg-0 { + margin-left: 0; + } + .offset-lg-1 { + margin-left: 8.33333333%; + } + .offset-lg-2 { + margin-left: 16.66666667%; + } + .offset-lg-3 { + margin-left: 25%; + } + .offset-lg-4 { + margin-left: 33.33333333%; + } + .offset-lg-5 { + margin-left: 41.66666667%; + } + .offset-lg-6 { + margin-left: 50%; + } + .offset-lg-7 { + margin-left: 58.33333333%; + } + .offset-lg-8 { + margin-left: 66.66666667%; + } + .offset-lg-9 { + margin-left: 75%; + } + .offset-lg-10 { + margin-left: 83.33333333%; + } + .offset-lg-11 { + margin-left: 91.66666667%; + } + .g-lg-0, + .gx-lg-0 { + --bs-gutter-x: 0; + } + .g-lg-0, + .gy-lg-0 { + --bs-gutter-y: 0; + } + .g-lg-1, + .gx-lg-1 { + --bs-gutter-x: 0.25rem; + } + .g-lg-1, + .gy-lg-1 { + --bs-gutter-y: 0.25rem; + } + .g-lg-2, + .gx-lg-2 { + --bs-gutter-x: 0.5rem; + } + .g-lg-2, + .gy-lg-2 { + --bs-gutter-y: 0.5rem; + } + .g-lg-3, + .gx-lg-3 { + --bs-gutter-x: 1rem; + } + .g-lg-3, + .gy-lg-3 { + --bs-gutter-y: 1rem; + } + .g-lg-4, + .gx-lg-4 { + --bs-gutter-x: 1.5rem; + } + .g-lg-4, + .gy-lg-4 { + --bs-gutter-y: 1.5rem; + } + .g-lg-5, + .gx-lg-5 { + --bs-gutter-x: 3rem; + } + .g-lg-5, + .gy-lg-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0%; + } + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xl-auto { + flex: 0 0 auto; + width: auto; + } + .col-xl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-xl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xl-3 { + flex: 0 0 auto; + width: 25%; + } + .col-xl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-xl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-xl-6 { + flex: 0 0 auto; + width: 50%; + } + .col-xl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-xl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-xl-9 { + flex: 0 0 auto; + width: 75%; + } + .col-xl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-xl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-xl-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-xl-0 { + margin-left: 0; + } + .offset-xl-1 { + margin-left: 8.33333333%; + } + .offset-xl-2 { + margin-left: 16.66666667%; + } + .offset-xl-3 { + margin-left: 25%; + } + .offset-xl-4 { + margin-left: 33.33333333%; + } + .offset-xl-5 { + margin-left: 41.66666667%; + } + .offset-xl-6 { + margin-left: 50%; + } + .offset-xl-7 { + margin-left: 58.33333333%; + } + .offset-xl-8 { + margin-left: 66.66666667%; + } + .offset-xl-9 { + margin-left: 75%; + } + .offset-xl-10 { + margin-left: 83.33333333%; + } + .offset-xl-11 { + margin-left: 91.66666667%; + } + .g-xl-0, + .gx-xl-0 { + --bs-gutter-x: 0; + } + .g-xl-0, + .gy-xl-0 { + --bs-gutter-y: 0; + } + .g-xl-1, + .gx-xl-1 { + --bs-gutter-x: 0.25rem; + } + .g-xl-1, + .gy-xl-1 { + --bs-gutter-y: 0.25rem; + } + .g-xl-2, + .gx-xl-2 { + --bs-gutter-x: 0.5rem; + } + .g-xl-2, + .gy-xl-2 { + --bs-gutter-y: 0.5rem; + } + .g-xl-3, + .gx-xl-3 { + --bs-gutter-x: 1rem; + } + .g-xl-3, + .gy-xl-3 { + --bs-gutter-y: 1rem; + } + .g-xl-4, + .gx-xl-4 { + --bs-gutter-x: 1.5rem; + } + .g-xl-4, + .gy-xl-4 { + --bs-gutter-y: 1.5rem; + } + .g-xl-5, + .gx-xl-5 { + --bs-gutter-x: 3rem; + } + .g-xl-5, + .gy-xl-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0%; + } + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xxl-auto { + flex: 0 0 auto; + width: auto; + } + .col-xxl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-xxl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xxl-3 { + flex: 0 0 auto; + width: 25%; + } + .col-xxl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-xxl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-xxl-6 { + flex: 0 0 auto; + width: 50%; + } + .col-xxl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-xxl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-xxl-9 { + flex: 0 0 auto; + width: 75%; + } + .col-xxl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-xxl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-xxl-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-xxl-0 { + margin-left: 0; + } + .offset-xxl-1 { + margin-left: 8.33333333%; + } + .offset-xxl-2 { + margin-left: 16.66666667%; + } + .offset-xxl-3 { + margin-left: 25%; + } + .offset-xxl-4 { + margin-left: 33.33333333%; + } + .offset-xxl-5 { + margin-left: 41.66666667%; + } + .offset-xxl-6 { + margin-left: 50%; + } + .offset-xxl-7 { + margin-left: 58.33333333%; + } + .offset-xxl-8 { + margin-left: 66.66666667%; + } + .offset-xxl-9 { + margin-left: 75%; + } + .offset-xxl-10 { + margin-left: 83.33333333%; + } + .offset-xxl-11 { + margin-left: 91.66666667%; + } + .g-xxl-0, + .gx-xxl-0 { + --bs-gutter-x: 0; + } + .g-xxl-0, + .gy-xxl-0 { + --bs-gutter-y: 0; + } + .g-xxl-1, + .gx-xxl-1 { + --bs-gutter-x: 0.25rem; + } + .g-xxl-1, + .gy-xxl-1 { + --bs-gutter-y: 0.25rem; + } + .g-xxl-2, + .gx-xxl-2 { + --bs-gutter-x: 0.5rem; + } + .g-xxl-2, + .gy-xxl-2 { + --bs-gutter-y: 0.5rem; + } + .g-xxl-3, + .gx-xxl-3 { + --bs-gutter-x: 1rem; + } + .g-xxl-3, + .gy-xxl-3 { + --bs-gutter-y: 1rem; + } + .g-xxl-4, + .gx-xxl-4 { + --bs-gutter-x: 1.5rem; + } + .g-xxl-4, + .gy-xxl-4 { + --bs-gutter-y: 1.5rem; + } + .g-xxl-5, + .gx-xxl-5 { + --bs-gutter-x: 3rem; + } + .g-xxl-5, + .gy-xxl-5 { + --bs-gutter-y: 3rem; + } +} +.table { + --bs-table-color-type: initial; + --bs-table-bg-type: initial; + --bs-table-color-state: initial; + --bs-table-bg-state: initial; + --bs-table-color: var(--bs-emphasis-color); + --bs-table-bg: var(--bs-body-bg); + --bs-table-border-color: var(--bs-border-color); + --bs-table-accent-bg: transparent; + --bs-table-striped-color: var(--bs-emphasis-color); + --bs-table-striped-bg: rgba(var(--bs-emphasis-color-rgb), 0.05); + --bs-table-active-color: var(--bs-emphasis-color); + --bs-table-active-bg: rgba(var(--bs-emphasis-color-rgb), 0.1); + --bs-table-hover-color: var(--bs-emphasis-color); + --bs-table-hover-bg: rgba(var(--bs-emphasis-color-rgb), 0.075); + width: 100%; + margin-bottom: 1rem; + vertical-align: top; + border-color: var(--bs-table-border-color); +} +.table > :not(caption) > * > * { + padding: 1rem 1rem; + color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color))); + background-color: var(--bs-table-bg); + border-bottom-width: var(--bs-border-width); + box-shadow: inset 0 0 0 9999px var(--bs-table-bg-state, var(--bs-table-bg-type, var(--bs-table-accent-bg))); +} +.table > tbody { + vertical-align: inherit; +} +.table > thead { + vertical-align: bottom; +} + +.table-group-divider { + border-top: calc(var(--bs-border-width) * 2) solid currentcolor; +} + +.caption-top { + caption-side: top; +} + +.table-sm > :not(caption) > * > * { + padding: 0.5rem 0.5rem; +} + +.table-bordered > :not(caption) > * { + border-width: var(--bs-border-width) 0; +} +.table-bordered > :not(caption) > * > * { + border-width: 0 var(--bs-border-width); +} + +.table-borderless > :not(caption) > * > * { + border-bottom-width: 0; +} +.table-borderless > :not(:first-child) { + border-top-width: 0; +} + +.table-striped > tbody > tr:nth-of-type(odd) > * { + --bs-table-color-type: var(--bs-table-striped-color); + --bs-table-bg-type: var(--bs-table-striped-bg); +} + +.table-striped-columns > :not(caption) > tr > :nth-child(even) { + --bs-table-color-type: var(--bs-table-striped-color); + --bs-table-bg-type: var(--bs-table-striped-bg); +} + +.table-active { + --bs-table-color-state: var(--bs-table-active-color); + --bs-table-bg-state: var(--bs-table-active-bg); +} + +.table-hover > tbody > tr:hover > * { + --bs-table-color-state: var(--bs-table-hover-color); + --bs-table-bg-state: var(--bs-table-hover-bg); +} + +.table-primary { + --bs-table-color: #000; + --bs-table-bg: #d6defa; + --bs-table-border-color: #abb2c8; + --bs-table-striped-bg: #cbd3ee; + --bs-table-striped-color: #000; + --bs-table-active-bg: #c1c8e1; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #c6cde7; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-secondary { + --bs-table-color: #000; + --bs-table-bg: white; + --bs-table-border-color: #cccccc; + --bs-table-striped-bg: #f2f2f2; + --bs-table-striped-color: #000; + --bs-table-active-bg: #e6e6e6; + --bs-table-active-color: #000; + --bs-table-hover-bg: #ececec; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-success { + --bs-table-color: #000; + --bs-table-bg: #d5f0e6; + --bs-table-border-color: #aac0b8; + --bs-table-striped-bg: #cae4db; + --bs-table-striped-color: #000; + --bs-table-active-bg: #c0d8cf; + --bs-table-active-color: #000; + --bs-table-hover-bg: #c5ded5; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-info { + --bs-table-color: #000; + --bs-table-bg: #d4e5f0; + --bs-table-border-color: #aab7c0; + --bs-table-striped-bg: #c9dae4; + --bs-table-striped-color: #000; + --bs-table-active-bg: #bfced8; + --bs-table-active-color: #000; + --bs-table-hover-bg: #c4d4de; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-warning { + --bs-table-color: #000; + --bs-table-bg: #fdf2df; + --bs-table-border-color: #cac2b2; + --bs-table-striped-bg: #f0e6d4; + --bs-table-striped-color: #000; + --bs-table-active-bg: #e4dac9; + --bs-table-active-color: #000; + --bs-table-hover-bg: #eae0ce; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-danger { + --bs-table-color: #000; + --bs-table-bg: #f8d4d5; + --bs-table-border-color: #c6aaaa; + --bs-table-striped-bg: #ecc9ca; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfbfc0; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #e5c4c5; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-light { + --bs-table-color: #000; + --bs-table-bg: #f8f9fa; + --bs-table-border-color: #c6c7c8; + --bs-table-striped-bg: #ecedee; + --bs-table-striped-color: #000; + --bs-table-active-bg: #dfe0e1; + --bs-table-active-color: #000; + --bs-table-hover-bg: #e5e6e7; + --bs-table-hover-color: #000; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-dark { + --bs-table-color: #fff; + --bs-table-bg: #212529; + --bs-table-border-color: #4d5154; + --bs-table-striped-bg: #2c3034; + --bs-table-striped-color: #fff; + --bs-table-active-bg: #373b3e; + --bs-table-active-color: #fff; + --bs-table-hover-bg: #323539; + --bs-table-hover-color: #fff; + color: var(--bs-table-color); + border-color: var(--bs-table-border-color); +} + +.table-responsive { + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 767.98px) { + .table-responsive-md { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 991.98px) { + .table-responsive-lg { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 1199.98px) { + .table-responsive-xl { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +@media (max-width: 1399.98px) { + .table-responsive-xxl { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } +} +.form-label { + margin-bottom: 0.5rem; + font-weight: 500; +} + +.col-form-label { + padding-top: calc(0.5rem + var(--bs-border-width)); + padding-bottom: calc(0.5rem + var(--bs-border-width)); + margin-bottom: 0; + font-size: inherit; + font-weight: 500; + line-height: 1.5; +} + +.col-form-label-lg { + padding-top: calc(0.5rem + var(--bs-border-width)); + padding-bottom: calc(0.5rem + var(--bs-border-width)); + font-size: 1.25rem; +} + +.col-form-label-sm { + padding-top: calc(0.25rem + var(--bs-border-width)); + padding-bottom: calc(0.25rem + var(--bs-border-width)); + font-size: 0.875rem; +} + +.form-text { + margin-top: 0.25rem; + font-size: 0.875em; + color: var(--bs-secondary-color); +} + +.form-control { + display: block; + width: 100%; + padding: 0.5rem 1rem; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.5; + color: var(--bs-body-color); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: var(--bs-body-bg); + background-clip: padding-box; + border: var(--bs-border-width) solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control { + transition: none; + } +} +.form-control[type=file] { + overflow: hidden; +} +.form-control[type=file]:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control:focus { + color: var(--bs-body-color); + background-color: var(--bs-body-bg); + border-color: #9aacf3; + outline: 0; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 0 0 0.25rem rgba(52, 89, 230, 0.25); +} +.form-control::-webkit-date-and-time-value { + min-width: 85px; + height: 1.5em; + margin: 0; +} +.form-control::-webkit-datetime-edit { + display: block; + padding: 0; +} +.form-control::-moz-placeholder { + color: var(--bs-secondary-color); + opacity: 1; +} +.form-control::placeholder { + color: var(--bs-secondary-color); + opacity: 1; +} +.form-control:disabled { + background-color: var(--bs-secondary-bg); + opacity: 1; +} +.form-control::-webkit-file-upload-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem; + color: var(--bs-body-color); + background-color: var(--bs-tertiary-bg); + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: var(--bs-border-width); + border-radius: 0; + -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +.form-control::file-selector-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem; + color: var(--bs-body-color); + background-color: var(--bs-tertiary-bg); + pointer-events: none; + border-color: inherit; + border-style: solid; + border-width: 0; + border-inline-end-width: var(--bs-border-width); + border-radius: 0; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control::-webkit-file-upload-button { + -webkit-transition: none; + transition: none; + } + .form-control::file-selector-button { + transition: none; + } +} +.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button { + background-color: var(--bs-secondary-bg); +} +.form-control:hover:not(:disabled):not([readonly])::file-selector-button { + background-color: var(--bs-secondary-bg); +} + +.form-control-plaintext { + display: block; + width: 100%; + padding: 0.5rem 0; + margin-bottom: 0; + line-height: 1.5; + color: var(--bs-body-color); + background-color: transparent; + border: solid transparent; + border-width: var(--bs-border-width) 0; +} +.form-control-plaintext:focus { + outline: 0; +} +.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg { + padding-right: 0; + padding-left: 0; +} + +.form-control-sm { + min-height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2)); + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: var(--bs-border-radius-sm); +} +.form-control-sm::-webkit-file-upload-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + -webkit-margin-end: 0.5rem; + margin-inline-end: 0.5rem; +} +.form-control-sm::file-selector-button { + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; + -webkit-margin-end: 0.5rem; + margin-inline-end: 0.5rem; +} + +.form-control-lg { + min-height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2)); + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: var(--bs-border-radius-lg); +} +.form-control-lg::-webkit-file-upload-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem; +} +.form-control-lg::file-selector-button { + padding: 0.5rem 1rem; + margin: -0.5rem -1rem; + -webkit-margin-end: 1rem; + margin-inline-end: 1rem; +} + +textarea.form-control { + min-height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2)); +} +textarea.form-control-sm { + min-height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2)); +} +textarea.form-control-lg { + min-height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2)); +} + +.form-control-color { + width: 3rem; + height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2)); + padding: 0.5rem; +} +.form-control-color:not(:disabled):not([readonly]) { + cursor: pointer; +} +.form-control-color::-moz-color-swatch { + border: 0 !important; + border-radius: var(--bs-border-radius); +} +.form-control-color::-webkit-color-swatch { + border: 0 !important; + border-radius: var(--bs-border-radius); +} +.form-control-color.form-control-sm { + height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2)); +} +.form-control-color.form-control-lg { + height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2)); +} + +.form-select { + --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); + display: block; + width: 100%; + padding: 0.5rem 3rem 0.5rem 1rem; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.5; + color: var(--bs-body-color); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: var(--bs-body-bg); + background-image: var(--bs-form-select-bg-img), var(--bs-form-select-bg-icon, none); + background-repeat: no-repeat; + background-position: right 1rem center; + background-size: 16px 12px; + border: var(--bs-border-width) solid var(--bs-border-color); + border-radius: var(--bs-border-radius); + box-shadow: var(--bs-box-shadow-inset); + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-select { + transition: none; + } +} +.form-select:focus { + border-color: #9aacf3; + outline: 0; + box-shadow: var(--bs-box-shadow-inset), 0 0 0 0.25rem rgba(52, 89, 230, 0.25); +} +.form-select[multiple], .form-select[size]:not([size="1"]) { + padding-right: 1rem; + background-image: none; +} +.form-select:disabled { + background-color: var(--bs-secondary-bg); +} +.form-select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 var(--bs-body-color); +} + +.form-select-sm { + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-left: 0.5rem; + font-size: 0.875rem; + border-radius: var(--bs-border-radius-sm); +} + +.form-select-lg { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + padding-left: 1rem; + font-size: 1.25rem; + border-radius: var(--bs-border-radius-lg); +} + +[data-bs-theme=dark] .form-select { + --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23dee2e6' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e"); +} + +.form-check { + display: block; + min-height: 1.5rem; + padding-left: 1.5em; + margin-bottom: 0.125rem; +} +.form-check .form-check-input { + float: left; + margin-left: -1.5em; +} + +.form-check-reverse { + padding-right: 1.5em; + padding-left: 0; + text-align: right; +} +.form-check-reverse .form-check-input { + float: right; + margin-right: -1.5em; + margin-left: 0; +} + +.form-check-input { + --bs-form-check-bg: var(--bs-body-bg); + flex-shrink: 0; + width: 1em; + height: 1em; + margin-top: 0.25em; + vertical-align: top; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: var(--bs-form-check-bg); + background-image: var(--bs-form-check-bg-image); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + border: var(--bs-border-width) solid var(--bs-border-color); + -webkit-print-color-adjust: exact; + color-adjust: exact; + print-color-adjust: exact; +} +.form-check-input[type=checkbox] { + border-radius: 0.25em; +} +.form-check-input[type=radio] { + border-radius: 50%; +} +.form-check-input:active { + filter: brightness(90%); +} +.form-check-input:focus { + border-color: #9aacf3; + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(52, 89, 230, 0.25); +} +.form-check-input:checked { + background-color: #3459e6; + border-color: #3459e6; +} +.form-check-input:checked[type=checkbox] { + --bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e"); +} +.form-check-input:checked[type=radio] { + --bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e"); +} +.form-check-input[type=checkbox]:indeterminate { + background-color: #3459e6; + border-color: #3459e6; + --bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e"); +} +.form-check-input:disabled { + pointer-events: none; + filter: none; + opacity: 0.5; +} +.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label { + cursor: default; + opacity: 0.5; +} + +.form-switch { + padding-left: 2.5em; +} +.form-switch .form-check-input { + --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e"); + width: 2em; + margin-left: -2.5em; + background-image: var(--bs-form-switch-bg); + background-position: left center; + border-radius: 2em; + transition: background-position 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-switch .form-check-input { + transition: none; + } +} +.form-switch .form-check-input:focus { + --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%239aacf3'/%3e%3c/svg%3e"); +} +.form-switch .form-check-input:checked { + background-position: right center; + --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); +} +.form-switch.form-check-reverse { + padding-right: 2.5em; + padding-left: 0; +} +.form-switch.form-check-reverse .form-check-input { + margin-right: -2.5em; + margin-left: 0; +} + +.form-check-inline { + display: inline-block; + margin-right: 1rem; +} + +.btn-check { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.btn-check[disabled] + .btn, .btn-check:disabled + .btn { + pointer-events: none; + filter: none; + opacity: 0.65; +} + +[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus) { + --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e"); +} + +.form-range { + width: 100%; + height: 1.5rem; + padding: 0; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: transparent; +} +.form-range:focus { + outline: 0; +} +.form-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(52, 89, 230, 0.25); +} +.form-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(52, 89, 230, 0.25); +} +.form-range::-moz-focus-outer { + border: 0; +} +.form-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -0.25rem; + -webkit-appearance: none; + appearance: none; + background-color: #3459e6; + border: 0; + border-radius: 1rem; + box-shadow: 0 0.1rem 0.25rem rgba(0, 0, 0, 0.1); + -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-range::-webkit-slider-thumb { + -webkit-transition: none; + transition: none; + } +} +.form-range::-webkit-slider-thumb:active { + background-color: #c2cdf8; +} +.form-range::-webkit-slider-runnable-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: var(--bs-secondary-bg); + border-color: transparent; + border-radius: 1rem; + box-shadow: var(--bs-box-shadow-inset); +} +.form-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + -moz-appearance: none; + appearance: none; + background-color: #3459e6; + border: 0; + border-radius: 1rem; + box-shadow: 0 0.1rem 0.25rem rgba(0, 0, 0, 0.1); + -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-range::-moz-range-thumb { + -moz-transition: none; + transition: none; + } +} +.form-range::-moz-range-thumb:active { + background-color: #c2cdf8; +} +.form-range::-moz-range-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: var(--bs-secondary-bg); + border-color: transparent; + border-radius: 1rem; + box-shadow: var(--bs-box-shadow-inset); +} +.form-range:disabled { + pointer-events: none; +} +.form-range:disabled::-webkit-slider-thumb { + background-color: var(--bs-secondary-color); +} +.form-range:disabled::-moz-range-thumb { + background-color: var(--bs-secondary-color); +} + +.form-floating { + position: relative; +} +.form-floating > .form-control, +.form-floating > .form-control-plaintext, +.form-floating > .form-select { + height: calc(3.5rem + calc(var(--bs-border-width) * 2)); + min-height: calc(3.5rem + calc(var(--bs-border-width) * 2)); + line-height: 1.25; +} +.form-floating > label { + position: absolute; + top: 0; + left: 0; + z-index: 2; + height: 100%; + padding: 1rem 1rem; + overflow: hidden; + text-align: start; + text-overflow: ellipsis; + white-space: nowrap; + pointer-events: none; + border: var(--bs-border-width) solid transparent; + transform-origin: 0 0; + transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-floating > label { + transition: none; + } +} +.form-floating > .form-control, +.form-floating > .form-control-plaintext { + padding: 1rem 1rem; +} +.form-floating > .form-control::-moz-placeholder, .form-floating > .form-control-plaintext::-moz-placeholder { + color: transparent; +} +.form-floating > .form-control::placeholder, +.form-floating > .form-control-plaintext::placeholder { + color: transparent; +} +.form-floating > .form-control:not(:-moz-placeholder-shown), .form-floating > .form-control-plaintext:not(:-moz-placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown), +.form-floating > .form-control-plaintext:focus, +.form-floating > .form-control-plaintext:not(:placeholder-shown) { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:-webkit-autofill, +.form-floating > .form-control-plaintext:-webkit-autofill { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-select { + padding-top: 1.625rem; + padding-bottom: 0.625rem; +} +.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label { + color: rgba(var(--bs-body-color-rgb), 0.65); + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control:focus ~ label, +.form-floating > .form-control:not(:placeholder-shown) ~ label, +.form-floating > .form-control-plaintext ~ label, +.form-floating > .form-select ~ label { + color: rgba(var(--bs-body-color-rgb), 0.65); + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label::after { + position: absolute; + inset: 1rem 0.5rem; + z-index: -1; + height: 1.5em; + content: ""; + background-color: var(--bs-body-bg); + border-radius: var(--bs-border-radius); +} +.form-floating > .form-control:focus ~ label::after, +.form-floating > .form-control:not(:placeholder-shown) ~ label::after, +.form-floating > .form-control-plaintext ~ label::after, +.form-floating > .form-select ~ label::after { + position: absolute; + inset: 1rem 0.5rem; + z-index: -1; + height: 1.5em; + content: ""; + background-color: var(--bs-body-bg); + border-radius: var(--bs-border-radius); +} +.form-floating > .form-control:-webkit-autofill ~ label { + color: rgba(var(--bs-body-color-rgb), 0.65); + transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem); +} +.form-floating > .form-control-plaintext ~ label { + border-width: var(--bs-border-width) 0; +} +.form-floating > :disabled ~ label, +.form-floating > .form-control:disabled ~ label { + color: #6c757d; +} +.form-floating > :disabled ~ label::after, +.form-floating > .form-control:disabled ~ label::after { + background-color: var(--bs-secondary-bg); +} + +.input-group { + position: relative; + display: flex; + flex-wrap: wrap; + align-items: stretch; + width: 100%; +} +.input-group > .form-control, +.input-group > .form-select, +.input-group > .form-floating { + position: relative; + flex: 1 1 auto; + width: 1%; + min-width: 0; +} +.input-group > .form-control:focus, +.input-group > .form-select:focus, +.input-group > .form-floating:focus-within { + z-index: 5; +} +.input-group .btn { + position: relative; + z-index: 2; +} +.input-group .btn:focus { + z-index: 5; +} + +.input-group-text { + display: flex; + align-items: center; + padding: 0.5rem 1rem; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.5; + color: var(--bs-body-color); + text-align: center; + white-space: nowrap; + background-color: var(--bs-tertiary-bg); + border: var(--bs-border-width) solid var(--bs-border-color); + border-radius: var(--bs-border-radius); +} + +.input-group-lg > .form-control, +.input-group-lg > .form-select, +.input-group-lg > .input-group-text, +.input-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + border-radius: var(--bs-border-radius-lg); +} + +.input-group-sm > .form-control, +.input-group-sm > .form-select, +.input-group-sm > .input-group-text, +.input-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + border-radius: var(--bs-border-radius-sm); +} + +.input-group-lg > .form-select, +.input-group-sm > .form-select { + padding-right: 4rem; +} + +.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating), +.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3), +.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control, +.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating), +.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4), +.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-control, +.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-select { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) { + margin-left: calc(var(--bs-border-width) * -1); + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group > .form-floating:not(:first-child) > .form-control, +.input-group > .form-floating:not(:first-child) > .form-select { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 0.875em; + color: var(--bs-form-valid-color); +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: 0.25rem 0.5rem; + margin-top: 0.1rem; + font-size: 0.875rem; + color: #fff; + background-color: var(--bs-success); + border-radius: var(--bs-border-radius); +} + +.was-validated :valid ~ .valid-feedback, +.was-validated :valid ~ .valid-tooltip, +.is-valid ~ .valid-feedback, +.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .form-control:valid, .form-control.is-valid { + border-color: var(--bs-form-valid-border-color); + padding-right: calc(1.5em + 1rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%232fb380' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.25rem) center; + background-size: calc(0.75em + 0.5rem) calc(0.75em + 0.5rem); +} +.was-validated .form-control:valid:focus, .form-control.is-valid:focus { + border-color: var(--bs-form-valid-border-color); + box-shadow: 0 0 0 0.25rem rgba(var(--bs-success-rgb), 0.25); +} + +.was-validated textarea.form-control:valid, textarea.form-control.is-valid { + padding-right: calc(1.5em + 1rem); + background-position: top calc(0.375em + 0.25rem) right calc(0.375em + 0.25rem); +} + +.was-validated .form-select:valid, .form-select.is-valid { + border-color: var(--bs-form-valid-border-color); +} +.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size="1"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size="1"] { + --bs-form-select-bg-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%232fb380' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + padding-right: 5.5rem; + background-position: right 1rem center, center right 3rem; + background-size: 16px 12px, calc(0.75em + 0.5rem) calc(0.75em + 0.5rem); +} +.was-validated .form-select:valid:focus, .form-select.is-valid:focus { + border-color: var(--bs-form-valid-border-color); + box-shadow: 0 0 0 0.25rem rgba(var(--bs-success-rgb), 0.25); +} + +.was-validated .form-control-color:valid, .form-control-color.is-valid { + width: calc(3rem + calc(1.5em + 1rem)); +} + +.was-validated .form-check-input:valid, .form-check-input.is-valid { + border-color: var(--bs-form-valid-border-color); +} +.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked { + background-color: var(--bs-form-valid-color); +} +.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus { + box-shadow: 0 0 0 0.25rem rgba(var(--bs-success-rgb), 0.25); +} +.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { + color: var(--bs-form-valid-color); +} + +.form-check-inline .form-check-input ~ .valid-feedback { + margin-left: 0.5em; +} + +.was-validated .input-group > .form-control:not(:focus):valid, .input-group > .form-control:not(:focus).is-valid, +.was-validated .input-group > .form-select:not(:focus):valid, +.input-group > .form-select:not(:focus).is-valid, +.was-validated .input-group > .form-floating:not(:focus-within):valid, +.input-group > .form-floating:not(:focus-within).is-valid { + z-index: 3; +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 0.875em; + color: var(--bs-form-invalid-color); +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: 0.25rem 0.5rem; + margin-top: 0.1rem; + font-size: 0.875rem; + color: #fff; + background-color: var(--bs-danger); + border-radius: var(--bs-border-radius); +} + +.was-validated :invalid ~ .invalid-feedback, +.was-validated :invalid ~ .invalid-tooltip, +.is-invalid ~ .invalid-feedback, +.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .form-control:invalid, .form-control.is-invalid { + border-color: var(--bs-form-invalid-border-color); + padding-right: calc(1.5em + 1rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23da292e'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23da292e' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.25rem) center; + background-size: calc(0.75em + 0.5rem) calc(0.75em + 0.5rem); +} +.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus { + border-color: var(--bs-form-invalid-border-color); + box-shadow: 0 0 0 0.25rem rgba(var(--bs-danger-rgb), 0.25); +} + +.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { + padding-right: calc(1.5em + 1rem); + background-position: top calc(0.375em + 0.25rem) right calc(0.375em + 0.25rem); +} + +.was-validated .form-select:invalid, .form-select.is-invalid { + border-color: var(--bs-form-invalid-border-color); +} +.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size="1"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size="1"] { + --bs-form-select-bg-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23da292e'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23da292e' stroke='none'/%3e%3c/svg%3e"); + padding-right: 5.5rem; + background-position: right 1rem center, center right 3rem; + background-size: 16px 12px, calc(0.75em + 0.5rem) calc(0.75em + 0.5rem); +} +.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus { + border-color: var(--bs-form-invalid-border-color); + box-shadow: 0 0 0 0.25rem rgba(var(--bs-danger-rgb), 0.25); +} + +.was-validated .form-control-color:invalid, .form-control-color.is-invalid { + width: calc(3rem + calc(1.5em + 1rem)); +} + +.was-validated .form-check-input:invalid, .form-check-input.is-invalid { + border-color: var(--bs-form-invalid-border-color); +} +.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked { + background-color: var(--bs-form-invalid-color); +} +.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus { + box-shadow: 0 0 0 0.25rem rgba(var(--bs-danger-rgb), 0.25); +} +.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { + color: var(--bs-form-invalid-color); +} + +.form-check-inline .form-check-input ~ .invalid-feedback { + margin-left: 0.5em; +} + +.was-validated .input-group > .form-control:not(:focus):invalid, .input-group > .form-control:not(:focus).is-invalid, +.was-validated .input-group > .form-select:not(:focus):invalid, +.input-group > .form-select:not(:focus).is-invalid, +.was-validated .input-group > .form-floating:not(:focus-within):invalid, +.input-group > .form-floating:not(:focus-within).is-invalid { + z-index: 4; +} + +.btn { + --bs-btn-padding-x: 1rem; + --bs-btn-padding-y: 0.5rem; + --bs-btn-font-family: ; + --bs-btn-font-size: 0.875rem; + --bs-btn-font-weight: 500; + --bs-btn-line-height: 1.5; + --bs-btn-color: var(--bs-body-color); + --bs-btn-bg: transparent; + --bs-btn-border-width: var(--bs-border-width); + --bs-btn-border-color: transparent; + --bs-btn-border-radius: var(--bs-border-radius); + --bs-btn-hover-border-color: transparent; + --bs-btn-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-opacity: 0.65; + --bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5); + display: inline-block; + padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x); + font-family: var(--bs-btn-font-family); + font-size: var(--bs-btn-font-size); + font-weight: var(--bs-btn-font-weight); + line-height: var(--bs-btn-line-height); + color: var(--bs-btn-color); + text-align: center; + text-decoration: none; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + border: var(--bs-btn-border-width) solid var(--bs-btn-border-color); + border-radius: var(--bs-btn-border-radius); + background-color: var(--bs-btn-bg); + box-shadow: var(--bs-btn-box-shadow); + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .btn { + transition: none; + } +} +.btn:hover { + color: var(--bs-btn-hover-color); + background-color: var(--bs-btn-hover-bg); + border-color: var(--bs-btn-hover-border-color); +} +.btn-check + .btn:hover { + color: var(--bs-btn-color); + background-color: var(--bs-btn-bg); + border-color: var(--bs-btn-border-color); +} +.btn:focus-visible { + color: var(--bs-btn-hover-color); + background-color: var(--bs-btn-hover-bg); + border-color: var(--bs-btn-hover-border-color); + outline: 0; + box-shadow: var(--bs-btn-box-shadow), var(--bs-btn-focus-box-shadow); +} +.btn-check:focus-visible + .btn { + border-color: var(--bs-btn-hover-border-color); + outline: 0; + box-shadow: var(--bs-btn-box-shadow), var(--bs-btn-focus-box-shadow); +} +.btn-check:checked + .btn, :not(.btn-check) + .btn:active, .btn:first-child:active, .btn.active, .btn.show { + color: var(--bs-btn-active-color); + background-color: var(--bs-btn-active-bg); + border-color: var(--bs-btn-active-border-color); + box-shadow: var(--bs-btn-active-shadow); +} +.btn-check:checked + .btn:focus-visible, :not(.btn-check) + .btn:active:focus-visible, .btn:first-child:active:focus-visible, .btn.active:focus-visible, .btn.show:focus-visible { + box-shadow: var(--bs-btn-active-shadow), var(--bs-btn-focus-box-shadow); +} +.btn:disabled, .btn.disabled, fieldset:disabled .btn { + color: var(--bs-btn-disabled-color); + pointer-events: none; + background-color: var(--bs-btn-disabled-bg); + border-color: var(--bs-btn-disabled-border-color); + opacity: var(--bs-btn-disabled-opacity); + box-shadow: none; +} + +.btn-primary { + --bs-btn-color: #fff; + --bs-btn-bg: #3459e6; + --bs-btn-border-color: #3459e6; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #2c4cc4; + --bs-btn-hover-border-color: #2a47b8; + --bs-btn-focus-shadow-rgb: 82, 114, 234; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #2a47b8; + --bs-btn-active-border-color: #2743ad; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #3459e6; + --bs-btn-disabled-border-color: #3459e6; +} + +.btn-secondary { + --bs-btn-color: #000; + --bs-btn-bg: #fff; + --bs-btn-border-color: #fff; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: white; + --bs-btn-hover-border-color: white; + --bs-btn-focus-shadow-rgb: 217, 217, 217; + --bs-btn-active-color: #000; + --bs-btn-active-bg: white; + --bs-btn-active-border-color: white; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #000; + --bs-btn-disabled-bg: #fff; + --bs-btn-disabled-border-color: #fff; +} + +.btn-success { + --bs-btn-color: #fff; + --bs-btn-bg: #2fb380; + --bs-btn-border-color: #2fb380; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #28986d; + --bs-btn-hover-border-color: #268f66; + --bs-btn-focus-shadow-rgb: 78, 190, 147; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #268f66; + --bs-btn-active-border-color: #238660; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #2fb380; + --bs-btn-disabled-border-color: #2fb380; +} + +.btn-info { + --bs-btn-color: #fff; + --bs-btn-bg: #287bb5; + --bs-btn-border-color: #287bb5; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #22699a; + --bs-btn-hover-border-color: #206291; + --bs-btn-focus-shadow-rgb: 72, 143, 192; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #206291; + --bs-btn-active-border-color: #1e5c88; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #287bb5; + --bs-btn-disabled-border-color: #287bb5; +} + +.btn-warning { + --bs-btn-color: #fff; + --bs-btn-bg: #f4bd61; + --bs-btn-border-color: #f4bd61; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #cfa152; + --bs-btn-hover-border-color: #c3974e; + --bs-btn-focus-shadow-rgb: 246, 199, 121; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #c3974e; + --bs-btn-active-border-color: #b78e49; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #f4bd61; + --bs-btn-disabled-border-color: #f4bd61; +} + +.btn-danger { + --bs-btn-color: #fff; + --bs-btn-bg: #da292e; + --bs-btn-border-color: #da292e; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #b92327; + --bs-btn-hover-border-color: #ae2125; + --bs-btn-focus-shadow-rgb: 224, 73, 77; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #ae2125; + --bs-btn-active-border-color: #a41f23; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #da292e; + --bs-btn-disabled-border-color: #da292e; +} + +.btn-light { + --bs-btn-color: #000; + --bs-btn-bg: #f8f9fa; + --bs-btn-border-color: #f8f9fa; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: #d3d4d5; + --bs-btn-hover-border-color: #c6c7c8; + --bs-btn-focus-shadow-rgb: 211, 212, 213; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #c6c7c8; + --bs-btn-active-border-color: #babbbc; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #000; + --bs-btn-disabled-bg: #f8f9fa; + --bs-btn-disabled-border-color: #f8f9fa; +} + +.btn-dark { + --bs-btn-color: #fff; + --bs-btn-bg: #212529; + --bs-btn-border-color: #212529; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #424649; + --bs-btn-hover-border-color: #373b3e; + --bs-btn-focus-shadow-rgb: 66, 70, 73; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #4d5154; + --bs-btn-active-border-color: #373b3e; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: #212529; + --bs-btn-disabled-border-color: #212529; +} + +.btn-outline-primary { + --bs-btn-color: #3459e6; + --bs-btn-border-color: #3459e6; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #3459e6; + --bs-btn-hover-border-color: #3459e6; + --bs-btn-focus-shadow-rgb: 52, 89, 230; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #3459e6; + --bs-btn-active-border-color: #3459e6; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #3459e6; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #3459e6; + --bs-gradient: none; +} + +.btn-outline-secondary { + --bs-btn-color: #fff; + --bs-btn-border-color: #fff; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: #fff; + --bs-btn-hover-border-color: #fff; + --bs-btn-focus-shadow-rgb: 255, 255, 255; + --bs-btn-active-color: #000; + --bs-btn-active-bg: #fff; + --bs-btn-active-border-color: #fff; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #fff; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #fff; + --bs-gradient: none; +} + +.btn-outline-success { + --bs-btn-color: #2fb380; + --bs-btn-border-color: #2fb380; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #2fb380; + --bs-btn-hover-border-color: #2fb380; + --bs-btn-focus-shadow-rgb: 47, 179, 128; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #2fb380; + --bs-btn-active-border-color: #2fb380; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #2fb380; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #2fb380; + --bs-gradient: none; +} + +.btn-outline-info { + --bs-btn-color: #287bb5; + --bs-btn-border-color: #287bb5; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #287bb5; + --bs-btn-hover-border-color: #287bb5; + --bs-btn-focus-shadow-rgb: 40, 123, 181; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #287bb5; + --bs-btn-active-border-color: #287bb5; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #287bb5; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #287bb5; + --bs-gradient: none; +} + +.btn-outline-warning { + --bs-btn-color: #f4bd61; + --bs-btn-border-color: #f4bd61; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #f4bd61; + --bs-btn-hover-border-color: #f4bd61; + --bs-btn-focus-shadow-rgb: 244, 189, 97; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #f4bd61; + --bs-btn-active-border-color: #f4bd61; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #f4bd61; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #f4bd61; + --bs-gradient: none; +} + +.btn-outline-danger { + --bs-btn-color: #da292e; + --bs-btn-border-color: #da292e; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #da292e; + --bs-btn-hover-border-color: #da292e; + --bs-btn-focus-shadow-rgb: 218, 41, 46; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #da292e; + --bs-btn-active-border-color: #da292e; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #da292e; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #da292e; + --bs-gradient: none; +} + +.btn-outline-light { + --bs-btn-color: #f8f9fa; + --bs-btn-border-color: #f8f9fa; + --bs-btn-hover-color: #000; + --bs-btn-hover-bg: #f8f9fa; + --bs-btn-hover-border-color: #f8f9fa; + --bs-btn-focus-shadow-rgb: 248, 249, 250; + --bs-btn-active-color: #000; + --bs-btn-active-bg: #f8f9fa; + --bs-btn-active-border-color: #f8f9fa; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #f8f9fa; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #f8f9fa; + --bs-gradient: none; +} + +.btn-outline-dark { + --bs-btn-color: #212529; + --bs-btn-border-color: #212529; + --bs-btn-hover-color: #fff; + --bs-btn-hover-bg: #212529; + --bs-btn-hover-border-color: #212529; + --bs-btn-focus-shadow-rgb: 33, 37, 41; + --bs-btn-active-color: #fff; + --bs-btn-active-bg: #212529; + --bs-btn-active-border-color: #212529; + --bs-btn-active-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-btn-disabled-color: #212529; + --bs-btn-disabled-bg: transparent; + --bs-btn-disabled-border-color: #212529; + --bs-gradient: none; +} + +.btn-link { + --bs-btn-font-weight: 400; + --bs-btn-color: var(--bs-link-color); + --bs-btn-bg: transparent; + --bs-btn-border-color: transparent; + --bs-btn-hover-color: var(--bs-link-hover-color); + --bs-btn-hover-border-color: transparent; + --bs-btn-active-color: var(--bs-link-hover-color); + --bs-btn-active-border-color: transparent; + --bs-btn-disabled-color: #6c757d; + --bs-btn-disabled-border-color: transparent; + --bs-btn-box-shadow: 0 0 0 #000; + --bs-btn-focus-shadow-rgb: 82, 114, 234; + text-decoration: underline; +} +.btn-link:focus-visible { + color: var(--bs-btn-color); +} +.btn-link:hover { + color: var(--bs-btn-hover-color); +} + +.btn-lg, .btn-group-lg > .btn { + --bs-btn-padding-y: 0.5rem; + --bs-btn-padding-x: 1rem; + --bs-btn-font-size: 1.25rem; + --bs-btn-border-radius: var(--bs-border-radius-lg); +} + +.btn-sm, .btn-group-sm > .btn { + --bs-btn-padding-y: 0.25rem; + --bs-btn-padding-x: 0.5rem; + --bs-btn-font-size: 0.875rem; + --bs-btn-border-radius: var(--bs-border-radius-sm); +} + +.fade { + transition: opacity 0.15s linear; +} +@media (prefers-reduced-motion: reduce) { + .fade { + transition: none; + } +} +.fade:not(.show) { + opacity: 0; +} + +.collapse:not(.show) { + display: none; +} + +.collapsing { + height: 0; + overflow: hidden; + transition: height 0.35s ease; +} +@media (prefers-reduced-motion: reduce) { + .collapsing { + transition: none; + } +} +.collapsing.collapse-horizontal { + width: 0; + height: auto; + transition: width 0.35s ease; +} +@media (prefers-reduced-motion: reduce) { + .collapsing.collapse-horizontal { + transition: none; + } +} + +.dropup, +.dropend, +.dropdown, +.dropstart, +.dropup-center, +.dropdown-center { + position: relative; +} + +.dropdown-toggle { + white-space: nowrap; +} +.dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-bottom: 0; + border-left: 0.3em solid transparent; +} +.dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropdown-menu { + --bs-dropdown-zindex: 1000; + --bs-dropdown-min-width: 10rem; + --bs-dropdown-padding-x: 0; + --bs-dropdown-padding-y: 0.5rem; + --bs-dropdown-spacer: 0.125rem; + --bs-dropdown-font-size: 0.875rem; + --bs-dropdown-color: var(--bs-body-color); + --bs-dropdown-bg: var(--bs-body-bg); + --bs-dropdown-border-color: #dee2e6; + --bs-dropdown-border-radius: var(--bs-border-radius); + --bs-dropdown-border-width: var(--bs-border-width); + --bs-dropdown-inner-border-radius: calc(var(--bs-border-radius) - var(--bs-border-width)); + --bs-dropdown-divider-bg: #e9ecef; + --bs-dropdown-divider-margin-y: 0.5rem; + --bs-dropdown-box-shadow: var(--bs-box-shadow); + --bs-dropdown-link-color: var(--bs-body-color); + --bs-dropdown-link-hover-color: #fff; + --bs-dropdown-link-hover-bg: #3459e6; + --bs-dropdown-link-active-color: #fff; + --bs-dropdown-link-active-bg: #3459e6; + --bs-dropdown-link-disabled-color: var(--bs-tertiary-color); + --bs-dropdown-item-padding-x: 1rem; + --bs-dropdown-item-padding-y: 0.5rem; + --bs-dropdown-header-color: #6c757d; + --bs-dropdown-header-padding-x: 1rem; + --bs-dropdown-header-padding-y: 0.5rem; + position: absolute; + z-index: var(--bs-dropdown-zindex); + display: none; + min-width: var(--bs-dropdown-min-width); + padding: var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x); + margin: 0; + font-size: var(--bs-dropdown-font-size); + color: var(--bs-dropdown-color); + text-align: left; + list-style: none; + background-color: var(--bs-dropdown-bg); + background-clip: padding-box; + border: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color); + border-radius: var(--bs-dropdown-border-radius); + box-shadow: var(--bs-dropdown-box-shadow); +} +.dropdown-menu[data-bs-popper] { + top: 100%; + left: 0; + margin-top: var(--bs-dropdown-spacer); +} + +.dropdown-menu-start { + --bs-position: start; +} +.dropdown-menu-start[data-bs-popper] { + right: auto; + left: 0; +} + +.dropdown-menu-end { + --bs-position: end; +} +.dropdown-menu-end[data-bs-popper] { + right: 0; + left: auto; +} + +@media (min-width: 576px) { + .dropdown-menu-sm-start { + --bs-position: start; + } + .dropdown-menu-sm-start[data-bs-popper] { + right: auto; + left: 0; + } + .dropdown-menu-sm-end { + --bs-position: end; + } + .dropdown-menu-sm-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 768px) { + .dropdown-menu-md-start { + --bs-position: start; + } + .dropdown-menu-md-start[data-bs-popper] { + right: auto; + left: 0; + } + .dropdown-menu-md-end { + --bs-position: end; + } + .dropdown-menu-md-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 992px) { + .dropdown-menu-lg-start { + --bs-position: start; + } + .dropdown-menu-lg-start[data-bs-popper] { + right: auto; + left: 0; + } + .dropdown-menu-lg-end { + --bs-position: end; + } + .dropdown-menu-lg-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 1200px) { + .dropdown-menu-xl-start { + --bs-position: start; + } + .dropdown-menu-xl-start[data-bs-popper] { + right: auto; + left: 0; + } + .dropdown-menu-xl-end { + --bs-position: end; + } + .dropdown-menu-xl-end[data-bs-popper] { + right: 0; + left: auto; + } +} +@media (min-width: 1400px) { + .dropdown-menu-xxl-start { + --bs-position: start; + } + .dropdown-menu-xxl-start[data-bs-popper] { + right: auto; + left: 0; + } + .dropdown-menu-xxl-end { + --bs-position: end; + } + .dropdown-menu-xxl-end[data-bs-popper] { + right: 0; + left: auto; + } +} +.dropup .dropdown-menu[data-bs-popper] { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: var(--bs-dropdown-spacer); +} +.dropup .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0; + border-right: 0.3em solid transparent; + border-bottom: 0.3em solid; + border-left: 0.3em solid transparent; +} +.dropup .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropend .dropdown-menu[data-bs-popper] { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: var(--bs-dropdown-spacer); +} +.dropend .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0; + border-bottom: 0.3em solid transparent; + border-left: 0.3em solid; +} +.dropend .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropend .dropdown-toggle::after { + vertical-align: 0; +} + +.dropstart .dropdown-menu[data-bs-popper] { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: var(--bs-dropdown-spacer); +} +.dropstart .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; +} +.dropstart .dropdown-toggle::after { + display: none; +} +.dropstart .dropdown-toggle::before { + display: inline-block; + margin-right: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0.3em solid; + border-bottom: 0.3em solid transparent; +} +.dropstart .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropstart .dropdown-toggle::before { + vertical-align: 0; +} + +.dropdown-divider { + height: 0; + margin: var(--bs-dropdown-divider-margin-y) 0; + overflow: hidden; + border-top: 1px solid var(--bs-dropdown-divider-bg); + opacity: 1; +} + +.dropdown-item { + display: block; + width: 100%; + padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x); + clear: both; + font-weight: 400; + color: var(--bs-dropdown-link-color); + text-align: inherit; + text-decoration: none; + white-space: nowrap; + background-color: transparent; + border: 0; + border-radius: var(--bs-dropdown-item-border-radius, 0); +} +.dropdown-item:hover, .dropdown-item:focus { + color: var(--bs-dropdown-link-hover-color); + background-color: var(--bs-dropdown-link-hover-bg); +} +.dropdown-item.active, .dropdown-item:active { + color: var(--bs-dropdown-link-active-color); + text-decoration: none; + background-color: var(--bs-dropdown-link-active-bg); +} +.dropdown-item.disabled, .dropdown-item:disabled { + color: var(--bs-dropdown-link-disabled-color); + pointer-events: none; + background-color: transparent; +} + +.dropdown-menu.show { + display: block; +} + +.dropdown-header { + display: block; + padding: var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x); + margin-bottom: 0; + font-size: 0.875rem; + color: var(--bs-dropdown-header-color); + white-space: nowrap; +} + +.dropdown-item-text { + display: block; + padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x); + color: var(--bs-dropdown-link-color); +} + +.dropdown-menu-dark { + --bs-dropdown-color: #dee2e6; + --bs-dropdown-bg: #343a40; + --bs-dropdown-border-color: #dee2e6; + --bs-dropdown-box-shadow: ; + --bs-dropdown-link-color: #dee2e6; + --bs-dropdown-link-hover-color: #fff; + --bs-dropdown-divider-bg: #e9ecef; + --bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15); + --bs-dropdown-link-active-color: #fff; + --bs-dropdown-link-active-bg: #3459e6; + --bs-dropdown-link-disabled-color: #adb5bd; + --bs-dropdown-header-color: #adb5bd; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-flex; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + flex: 1 1 auto; +} +.btn-group > .btn-check:checked + .btn, +.btn-group > .btn-check:focus + .btn, +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn-check:checked + .btn, +.btn-group-vertical > .btn-check:focus + .btn, +.btn-group-vertical > .btn:hover, +.btn-group-vertical > .btn:focus, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn.active { + z-index: 1; +} + +.btn-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: flex-start; +} +.btn-toolbar .input-group { + width: auto; +} + +.btn-group { + border-radius: var(--bs-border-radius); +} +.btn-group > :not(.btn-check:first-child) + .btn, +.btn-group > .btn-group:not(:first-child) { + margin-left: calc(var(--bs-border-width) * -1); +} +.btn-group > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group > .btn.dropdown-toggle-split:first-child, +.btn-group > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:nth-child(n+3), +.btn-group > :not(.btn-check) + .btn, +.btn-group > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} +.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after { + margin-left: 0; +} +.dropstart .dropdown-toggle-split::before { + margin-right: 0; +} + +.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { + padding-right: 0.375rem; + padding-left: 0.375rem; +} + +.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} + +.btn-group.show .dropdown-toggle { + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} +.btn-group.show .dropdown-toggle.btn-link { + box-shadow: none; +} + +.btn-group-vertical { + flex-direction: column; + align-items: flex-start; + justify-content: center; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group { + width: 100%; +} +.btn-group-vertical > .btn:not(:first-child), +.btn-group-vertical > .btn-group:not(:first-child) { + margin-top: calc(var(--bs-border-width) * -1); +} +.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group-vertical > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn ~ .btn, +.btn-group-vertical > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav { + --bs-nav-link-padding-x: 1rem; + --bs-nav-link-padding-y: 0.5rem; + --bs-nav-link-font-weight: ; + --bs-nav-link-color: #495057; + --bs-nav-link-hover-color: #495057; + --bs-nav-link-disabled-color: var(--bs-secondary-color); + display: flex; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x); + font-size: var(--bs-nav-link-font-size); + font-weight: var(--bs-nav-link-font-weight); + color: var(--bs-nav-link-color); + text-decoration: none; + background: none; + border: 0; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .nav-link { + transition: none; + } +} +.nav-link:hover, .nav-link:focus { + color: var(--bs-nav-link-hover-color); +} +.nav-link:focus-visible { + outline: 0; + box-shadow: 0 0 0 0.25rem rgba(52, 89, 230, 0.25); +} +.nav-link.disabled, .nav-link:disabled { + color: var(--bs-nav-link-disabled-color); + pointer-events: none; + cursor: default; +} + +.nav-tabs { + --bs-nav-tabs-border-width: var(--bs-border-width); + --bs-nav-tabs-border-color: var(--bs-border-color); + --bs-nav-tabs-border-radius: 0; + --bs-nav-tabs-link-hover-border-color: var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color); + --bs-nav-tabs-link-active-color: #3459e6; + --bs-nav-tabs-link-active-bg: var(--bs-body-bg); + --bs-nav-tabs-link-active-border-color: var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg); + border-bottom: var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color); +} +.nav-tabs .nav-link { + margin-bottom: calc(-1 * var(--bs-nav-tabs-border-width)); + border: var(--bs-nav-tabs-border-width) solid transparent; + border-top-left-radius: var(--bs-nav-tabs-border-radius); + border-top-right-radius: var(--bs-nav-tabs-border-radius); +} +.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { + isolation: isolate; + border-color: var(--bs-nav-tabs-link-hover-border-color); +} +.nav-tabs .nav-link.active, +.nav-tabs .nav-item.show .nav-link { + color: var(--bs-nav-tabs-link-active-color); + background-color: var(--bs-nav-tabs-link-active-bg); + border-color: var(--bs-nav-tabs-link-active-border-color); +} +.nav-tabs .dropdown-menu { + margin-top: calc(-1 * var(--bs-nav-tabs-border-width)); + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav-pills { + --bs-nav-pills-border-radius: var(--bs-border-radius); + --bs-nav-pills-link-active-color: #fff; + --bs-nav-pills-link-active-bg: #3459e6; +} +.nav-pills .nav-link { + border-radius: var(--bs-nav-pills-border-radius); +} +.nav-pills .nav-link.active, +.nav-pills .show > .nav-link { + color: var(--bs-nav-pills-link-active-color); + background-color: var(--bs-nav-pills-link-active-bg); +} + +.nav-underline { + --bs-nav-underline-gap: 1rem; + --bs-nav-underline-border-width: 0.125rem; + --bs-nav-underline-link-active-color: var(--bs-emphasis-color); + gap: var(--bs-nav-underline-gap); +} +.nav-underline .nav-link { + padding-right: 0; + padding-left: 0; + border-bottom: var(--bs-nav-underline-border-width) solid transparent; +} +.nav-underline .nav-link:hover, .nav-underline .nav-link:focus { + border-bottom-color: currentcolor; +} +.nav-underline .nav-link.active, +.nav-underline .show > .nav-link { + font-weight: 700; + color: var(--bs-nav-underline-link-active-color); + border-bottom-color: currentcolor; +} + +.nav-fill > .nav-link, +.nav-fill .nav-item { + flex: 1 1 auto; + text-align: center; +} + +.nav-justified > .nav-link, +.nav-justified .nav-item { + flex-basis: 0; + flex-grow: 1; + text-align: center; +} + +.nav-fill .nav-item .nav-link, +.nav-justified .nav-item .nav-link { + width: 100%; +} + +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} + +.navbar { + --bs-navbar-padding-x: 0; + --bs-navbar-padding-y: 0.85rem; + --bs-navbar-color: rgba(var(--bs-emphasis-color-rgb), 0.65); + --bs-navbar-hover-color: rgba(var(--bs-emphasis-color-rgb), 0.8); + --bs-navbar-disabled-color: rgba(var(--bs-emphasis-color-rgb), 0.3); + --bs-navbar-active-color: rgba(var(--bs-emphasis-color-rgb), 1); + --bs-navbar-brand-padding-y: 0.3125rem; + --bs-navbar-brand-margin-end: 1rem; + --bs-navbar-brand-font-size: 1.25rem; + --bs-navbar-brand-color: rgba(var(--bs-emphasis-color-rgb), 1); + --bs-navbar-brand-hover-color: rgba(var(--bs-emphasis-color-rgb), 1); + --bs-navbar-nav-link-padding-x: 0.75rem; + --bs-navbar-toggler-padding-y: 0.25rem; + --bs-navbar-toggler-padding-x: 0.75rem; + --bs-navbar-toggler-font-size: 1.25rem; + --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2873, 80, 87, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); + --bs-navbar-toggler-border-color: rgba(var(--bs-emphasis-color-rgb), 0.15); + --bs-navbar-toggler-border-radius: var(--bs-border-radius); + --bs-navbar-toggler-focus-width: 0.25rem; + --bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out; + position: relative; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + padding: var(--bs-navbar-padding-y) var(--bs-navbar-padding-x); +} +.navbar > .container, +.navbar > .container-fluid, +.navbar > .container-sm, +.navbar > .container-md, +.navbar > .container-lg, +.navbar > .container-xl, +.navbar > .container-xxl { + display: flex; + flex-wrap: inherit; + align-items: center; + justify-content: space-between; +} +.navbar-brand { + padding-top: var(--bs-navbar-brand-padding-y); + padding-bottom: var(--bs-navbar-brand-padding-y); + margin-right: var(--bs-navbar-brand-margin-end); + font-size: var(--bs-navbar-brand-font-size); + color: var(--bs-navbar-brand-color); + text-decoration: none; + white-space: nowrap; +} +.navbar-brand:hover, .navbar-brand:focus { + color: var(--bs-navbar-brand-hover-color); +} + +.navbar-nav { + --bs-nav-link-padding-x: 0; + --bs-nav-link-padding-y: 0.5rem; + --bs-nav-link-font-weight: ; + --bs-nav-link-color: var(--bs-navbar-color); + --bs-nav-link-hover-color: var(--bs-navbar-hover-color); + --bs-nav-link-disabled-color: var(--bs-navbar-disabled-color); + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.navbar-nav .nav-link.active, .navbar-nav .nav-link.show { + color: var(--bs-navbar-active-color); +} +.navbar-nav .dropdown-menu { + position: static; +} + +.navbar-text { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + color: var(--bs-navbar-color); +} +.navbar-text a, +.navbar-text a:hover, +.navbar-text a:focus { + color: var(--bs-navbar-active-color); +} + +.navbar-collapse { + flex-basis: 100%; + flex-grow: 1; + align-items: center; +} + +.navbar-toggler { + padding: var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x); + font-size: var(--bs-navbar-toggler-font-size); + line-height: 1; + color: var(--bs-navbar-color); + background-color: transparent; + border: var(--bs-border-width) solid var(--bs-navbar-toggler-border-color); + border-radius: var(--bs-navbar-toggler-border-radius); + transition: var(--bs-navbar-toggler-transition); +} +@media (prefers-reduced-motion: reduce) { + .navbar-toggler { + transition: none; + } +} +.navbar-toggler:hover { + text-decoration: none; +} +.navbar-toggler:focus { + text-decoration: none; + outline: 0; + box-shadow: 0 0 0 var(--bs-navbar-toggler-focus-width); +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + background-image: var(--bs-navbar-toggler-icon-bg); + background-repeat: no-repeat; + background-position: center; + background-size: 100%; +} + +.navbar-nav-scroll { + max-height: var(--bs-scroll-height, 75vh); + overflow-y: auto; +} + +@media (min-width: 576px) { + .navbar-expand-sm { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-sm .navbar-nav { + flex-direction: row; + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); + } + .navbar-expand-sm .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-sm .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-sm .navbar-toggler { + display: none; + } + .navbar-expand-sm .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + box-shadow: none; + transition: none; + } + .navbar-expand-sm .offcanvas .offcanvas-header { + display: none; + } + .navbar-expand-sm .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 768px) { + .navbar-expand-md { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-md .navbar-nav { + flex-direction: row; + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); + } + .navbar-expand-md .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-md .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-md .navbar-toggler { + display: none; + } + .navbar-expand-md .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + box-shadow: none; + transition: none; + } + .navbar-expand-md .offcanvas .offcanvas-header { + display: none; + } + .navbar-expand-md .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 992px) { + .navbar-expand-lg { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-lg .navbar-nav { + flex-direction: row; + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); + } + .navbar-expand-lg .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-lg .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-lg .navbar-toggler { + display: none; + } + .navbar-expand-lg .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + box-shadow: none; + transition: none; + } + .navbar-expand-lg .offcanvas .offcanvas-header { + display: none; + } + .navbar-expand-lg .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 1200px) { + .navbar-expand-xl { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-xl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); + } + .navbar-expand-xl .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-xl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xl .navbar-toggler { + display: none; + } + .navbar-expand-xl .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + box-shadow: none; + transition: none; + } + .navbar-expand-xl .offcanvas .offcanvas-header { + display: none; + } + .navbar-expand-xl .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +@media (min-width: 1400px) { + .navbar-expand-xxl { + flex-wrap: nowrap; + justify-content: flex-start; + } + .navbar-expand-xxl .navbar-nav { + flex-direction: row; + } + .navbar-expand-xxl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xxl .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); + } + .navbar-expand-xxl .navbar-nav-scroll { + overflow: visible; + } + .navbar-expand-xxl .navbar-collapse { + display: flex !important; + flex-basis: auto; + } + .navbar-expand-xxl .navbar-toggler { + display: none; + } + .navbar-expand-xxl .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + box-shadow: none; + transition: none; + } + .navbar-expand-xxl .offcanvas .offcanvas-header { + display: none; + } + .navbar-expand-xxl .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + } +} +.navbar-expand { + flex-wrap: nowrap; + justify-content: flex-start; +} +.navbar-expand .navbar-nav { + flex-direction: row; +} +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute; +} +.navbar-expand .navbar-nav .nav-link { + padding-right: var(--bs-navbar-nav-link-padding-x); + padding-left: var(--bs-navbar-nav-link-padding-x); +} +.navbar-expand .navbar-nav-scroll { + overflow: visible; +} +.navbar-expand .navbar-collapse { + display: flex !important; + flex-basis: auto; +} +.navbar-expand .navbar-toggler { + display: none; +} +.navbar-expand .offcanvas { + position: static; + z-index: auto; + flex-grow: 1; + width: auto !important; + height: auto !important; + visibility: visible !important; + background-color: transparent !important; + border: 0 !important; + transform: none !important; + box-shadow: none; + transition: none; +} +.navbar-expand .offcanvas .offcanvas-header { + display: none; +} +.navbar-expand .offcanvas .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; +} + +.navbar-dark, +.navbar[data-bs-theme=dark] { + --bs-navbar-color: rgba(255, 255, 255, 0.55); + --bs-navbar-hover-color: rgba(255, 255, 255, 0.75); + --bs-navbar-disabled-color: rgba(255, 255, 255, 0.25); + --bs-navbar-active-color: #fff; + --bs-navbar-brand-color: #fff; + --bs-navbar-brand-hover-color: #fff; + --bs-navbar-toggler-border-color: rgba(255, 255, 255, 0.1); + --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} + +[data-bs-theme=dark] .navbar-toggler-icon { + --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} + +.card { + --bs-card-spacer-y: 1rem; + --bs-card-spacer-x: 1.5rem; + --bs-card-title-spacer-y: 0.5rem; + --bs-card-title-color: ; + --bs-card-subtitle-color: ; + --bs-card-border-width: var(--bs-border-width); + --bs-card-border-color: var(--bs-border-color-translucent); + --bs-card-border-radius: var(--bs-border-radius); + --bs-card-box-shadow: ; + --bs-card-inner-border-radius: calc(var(--bs-border-radius) - (var(--bs-border-width))); + --bs-card-cap-padding-y: 1rem; + --bs-card-cap-padding-x: 1.5rem; + --bs-card-cap-bg: rgba(var(--bs-body-color-rgb), 0.03); + --bs-card-cap-color: ; + --bs-card-height: ; + --bs-card-color: ; + --bs-card-bg: var(--bs-body-bg); + --bs-card-img-overlay-padding: 1rem; + --bs-card-group-margin: 0.75rem; + position: relative; + display: flex; + flex-direction: column; + min-width: 0; + height: var(--bs-card-height); + color: var(--bs-body-color); + word-wrap: break-word; + background-color: var(--bs-card-bg); + background-clip: border-box; + border: var(--bs-card-border-width) solid var(--bs-card-border-color); + border-radius: var(--bs-card-border-radius); + box-shadow: var(--bs-card-box-shadow); +} +.card > hr { + margin-right: 0; + margin-left: 0; +} +.card > .list-group { + border-top: inherit; + border-bottom: inherit; +} +.card > .list-group:first-child { + border-top-width: 0; + border-top-left-radius: var(--bs-card-inner-border-radius); + border-top-right-radius: var(--bs-card-inner-border-radius); +} +.card > .list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: var(--bs-card-inner-border-radius); + border-bottom-left-radius: var(--bs-card-inner-border-radius); +} +.card > .card-header + .list-group, +.card > .list-group + .card-footer { + border-top: 0; +} + +.card-body { + flex: 1 1 auto; + padding: var(--bs-card-spacer-y) var(--bs-card-spacer-x); + color: var(--bs-card-color); +} + +.card-title { + margin-bottom: var(--bs-card-title-spacer-y); + color: var(--bs-card-title-color); +} + +.card-subtitle { + margin-top: calc(-0.5 * var(--bs-card-title-spacer-y)); + margin-bottom: 0; + color: var(--bs-card-subtitle-color); +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link + .card-link { + margin-left: var(--bs-card-spacer-x); +} + +.card-header { + padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x); + margin-bottom: 0; + color: var(--bs-card-cap-color); + background-color: var(--bs-card-cap-bg); + border-bottom: var(--bs-card-border-width) solid var(--bs-card-border-color); +} +.card-header:first-child { + border-radius: var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0; +} + +.card-footer { + padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x); + color: var(--bs-card-cap-color); + background-color: var(--bs-card-cap-bg); + border-top: var(--bs-card-border-width) solid var(--bs-card-border-color); +} +.card-footer:last-child { + border-radius: 0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius); +} + +.card-header-tabs { + margin-right: calc(-0.5 * var(--bs-card-cap-padding-x)); + margin-bottom: calc(-1 * var(--bs-card-cap-padding-y)); + margin-left: calc(-0.5 * var(--bs-card-cap-padding-x)); + border-bottom: 0; +} +.card-header-tabs .nav-link.active { + background-color: var(--bs-card-bg); + border-bottom-color: var(--bs-card-bg); +} + +.card-header-pills { + margin-right: calc(-0.5 * var(--bs-card-cap-padding-x)); + margin-left: calc(-0.5 * var(--bs-card-cap-padding-x)); +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: var(--bs-card-img-overlay-padding); + border-radius: var(--bs-card-inner-border-radius); +} + +.card-img, +.card-img-top, +.card-img-bottom { + width: 100%; +} + +.card-img, +.card-img-top { + border-top-left-radius: var(--bs-card-inner-border-radius); + border-top-right-radius: var(--bs-card-inner-border-radius); +} + +.card-img, +.card-img-bottom { + border-bottom-right-radius: var(--bs-card-inner-border-radius); + border-bottom-left-radius: var(--bs-card-inner-border-radius); +} + +.card-group > .card { + margin-bottom: var(--bs-card-group-margin); +} +@media (min-width: 576px) { + .card-group { + display: flex; + flex-flow: row wrap; + } + .card-group > .card { + flex: 1 0 0%; + margin-bottom: 0; + } + .card-group > .card + .card { + margin-left: 0; + border-left: 0; + } + .card-group > .card:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .card-group > .card:not(:last-child) .card-img-top, + .card-group > .card:not(:last-child) .card-header { + border-top-right-radius: 0; + } + .card-group > .card:not(:last-child) .card-img-bottom, + .card-group > .card:not(:last-child) .card-footer { + border-bottom-right-radius: 0; + } + .card-group > .card:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .card-group > .card:not(:first-child) .card-img-top, + .card-group > .card:not(:first-child) .card-header { + border-top-left-radius: 0; + } + .card-group > .card:not(:first-child) .card-img-bottom, + .card-group > .card:not(:first-child) .card-footer { + border-bottom-left-radius: 0; + } +} + +.accordion { + --bs-accordion-color: var(--bs-body-color); + --bs-accordion-bg: var(--bs-body-bg); + --bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease; + --bs-accordion-border-color: var(--bs-border-color); + --bs-accordion-border-width: var(--bs-border-width); + --bs-accordion-border-radius: var(--bs-border-radius); + --bs-accordion-inner-border-radius: calc(var(--bs-border-radius) - (var(--bs-border-width))); + --bs-accordion-btn-padding-x: 1.25rem; + --bs-accordion-btn-padding-y: 1rem; + --bs-accordion-btn-color: var(--bs-body-color); + --bs-accordion-btn-bg: var(--bs-accordion-bg); + --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23495057'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + --bs-accordion-btn-icon-width: 1.25rem; + --bs-accordion-btn-icon-transform: rotate(-180deg); + --bs-accordion-btn-icon-transition: transform 0.2s ease-in-out; + --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2315245c'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + --bs-accordion-btn-focus-border-color: #9aacf3; + --bs-accordion-btn-focus-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + --bs-accordion-body-padding-x: 1.25rem; + --bs-accordion-body-padding-y: 1rem; + --bs-accordion-active-color: var(--bs-primary-text-emphasis); + --bs-accordion-active-bg: var(--bs-primary-bg-subtle); +} + +.accordion-button { + position: relative; + display: flex; + align-items: center; + width: 100%; + padding: var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x); + font-size: 1rem; + color: var(--bs-accordion-btn-color); + text-align: left; + background-color: var(--bs-accordion-btn-bg); + border: 0; + border-radius: 0; + overflow-anchor: none; + transition: var(--bs-accordion-transition); +} +@media (prefers-reduced-motion: reduce) { + .accordion-button { + transition: none; + } +} +.accordion-button:not(.collapsed) { + color: var(--bs-accordion-active-color); + background-color: var(--bs-accordion-active-bg); + box-shadow: inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color); +} +.accordion-button:not(.collapsed)::after { + background-image: var(--bs-accordion-btn-active-icon); + transform: var(--bs-accordion-btn-icon-transform); +} +.accordion-button::after { + flex-shrink: 0; + width: var(--bs-accordion-btn-icon-width); + height: var(--bs-accordion-btn-icon-width); + margin-left: auto; + content: ""; + background-image: var(--bs-accordion-btn-icon); + background-repeat: no-repeat; + background-size: var(--bs-accordion-btn-icon-width); + transition: var(--bs-accordion-btn-icon-transition); +} +@media (prefers-reduced-motion: reduce) { + .accordion-button::after { + transition: none; + } +} +.accordion-button:hover { + z-index: 2; +} +.accordion-button:focus { + z-index: 3; + border-color: var(--bs-accordion-btn-focus-border-color); + outline: 0; + box-shadow: var(--bs-accordion-btn-focus-box-shadow); +} + +.accordion-header { + margin-bottom: 0; +} + +.accordion-item { + color: var(--bs-accordion-color); + background-color: var(--bs-accordion-bg); + border: var(--bs-accordion-border-width) solid var(--bs-accordion-border-color); +} +.accordion-item:first-of-type { + border-top-left-radius: var(--bs-accordion-border-radius); + border-top-right-radius: var(--bs-accordion-border-radius); +} +.accordion-item:first-of-type .accordion-button { + border-top-left-radius: var(--bs-accordion-inner-border-radius); + border-top-right-radius: var(--bs-accordion-inner-border-radius); +} +.accordion-item:not(:first-of-type) { + border-top: 0; +} +.accordion-item:last-of-type { + border-bottom-right-radius: var(--bs-accordion-border-radius); + border-bottom-left-radius: var(--bs-accordion-border-radius); +} +.accordion-item:last-of-type .accordion-button.collapsed { + border-bottom-right-radius: var(--bs-accordion-inner-border-radius); + border-bottom-left-radius: var(--bs-accordion-inner-border-radius); +} +.accordion-item:last-of-type .accordion-collapse { + border-bottom-right-radius: var(--bs-accordion-border-radius); + border-bottom-left-radius: var(--bs-accordion-border-radius); +} + +.accordion-body { + padding: var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x); +} + +.accordion-flush .accordion-collapse { + border-width: 0; +} +.accordion-flush .accordion-item { + border-right: 0; + border-left: 0; + border-radius: 0; +} +.accordion-flush .accordion-item:first-child { + border-top: 0; +} +.accordion-flush .accordion-item:last-child { + border-bottom: 0; +} +.accordion-flush .accordion-item .accordion-button, .accordion-flush .accordion-item .accordion-button.collapsed { + border-radius: 0; +} + +[data-bs-theme=dark] .accordion-button::after { + --bs-accordion-btn-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23859bf0'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); + --bs-accordion-btn-active-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23859bf0'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); +} + +.breadcrumb { + --bs-breadcrumb-padding-x: 1rem; + --bs-breadcrumb-padding-y: 0; + --bs-breadcrumb-margin-bottom: 1rem; + --bs-breadcrumb-bg: ; + --bs-breadcrumb-border-radius: ; + --bs-breadcrumb-divider-color: var(--bs-secondary-color); + --bs-breadcrumb-item-padding-x: 0.5rem; + --bs-breadcrumb-item-active-color: var(--bs-secondary-color); + display: flex; + flex-wrap: wrap; + padding: var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x); + margin-bottom: var(--bs-breadcrumb-margin-bottom); + font-size: var(--bs-breadcrumb-font-size); + list-style: none; + background-color: var(--bs-breadcrumb-bg); + border-radius: var(--bs-breadcrumb-border-radius); +} + +.breadcrumb-item + .breadcrumb-item { + padding-left: var(--bs-breadcrumb-item-padding-x); +} +.breadcrumb-item + .breadcrumb-item::before { + float: left; + padding-right: var(--bs-breadcrumb-item-padding-x); + color: var(--bs-breadcrumb-divider-color); + content: var(--bs-breadcrumb-divider, ">") /* rtl: var(--bs-breadcrumb-divider, ">") */; +} +.breadcrumb-item.active { + color: var(--bs-breadcrumb-item-active-color); +} + +.pagination { + --bs-pagination-padding-x: 1rem; + --bs-pagination-padding-y: 0.5rem; + --bs-pagination-font-size: 1rem; + --bs-pagination-color: var(--bs-primary-bg); + --bs-pagination-bg: var(--bs-body-bg); + --bs-pagination-border-width: var(--bs-border-width); + --bs-pagination-border-color: var(--bs-border-color); + --bs-pagination-border-radius: var(--bs-border-radius); + --bs-pagination-hover-color: var(--bs-primary-bg); + --bs-pagination-hover-bg: var(--bs-secondary-bg); + --bs-pagination-hover-border-color: var(--bs-border-color); + --bs-pagination-focus-color: var(--bs-primary-bg); + --bs-pagination-focus-bg: var(--bs-secondary-bg); + --bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(52, 89, 230, 0.25); + --bs-pagination-active-color: #fff; + --bs-pagination-active-bg: #3459e6; + --bs-pagination-active-border-color: #3459e6; + --bs-pagination-disabled-color: var(--bs-tertiary-color); + --bs-pagination-disabled-bg: var(--bs-tertiary-bg); + --bs-pagination-disabled-border-color: var(--bs-border-color); + display: flex; + padding-left: 0; + list-style: none; +} + +.page-link { + position: relative; + display: block; + padding: var(--bs-pagination-padding-y) var(--bs-pagination-padding-x); + font-size: var(--bs-pagination-font-size); + color: var(--bs-pagination-color); + text-decoration: none; + background-color: var(--bs-pagination-bg); + border: var(--bs-pagination-border-width) solid var(--bs-pagination-border-color); + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .page-link { + transition: none; + } +} +.page-link:hover { + z-index: 2; + color: var(--bs-pagination-hover-color); + background-color: var(--bs-pagination-hover-bg); + border-color: var(--bs-pagination-hover-border-color); +} +.page-link:focus { + z-index: 3; + color: var(--bs-pagination-focus-color); + background-color: var(--bs-pagination-focus-bg); + outline: 0; + box-shadow: var(--bs-pagination-focus-box-shadow); +} +.page-link.active, .active > .page-link { + z-index: 3; + color: var(--bs-pagination-active-color); + background-color: var(--bs-pagination-active-bg); + border-color: var(--bs-pagination-active-border-color); +} +.page-link.disabled, .disabled > .page-link { + color: var(--bs-pagination-disabled-color); + pointer-events: none; + background-color: var(--bs-pagination-disabled-bg); + border-color: var(--bs-pagination-disabled-border-color); +} + +.page-item:not(:first-child) .page-link { + margin-left: calc(var(--bs-border-width) * -1); +} +.page-item:first-child .page-link { + border-top-left-radius: var(--bs-pagination-border-radius); + border-bottom-left-radius: var(--bs-pagination-border-radius); +} +.page-item:last-child .page-link { + border-top-right-radius: var(--bs-pagination-border-radius); + border-bottom-right-radius: var(--bs-pagination-border-radius); +} + +.pagination-lg { + --bs-pagination-padding-x: 1.5rem; + --bs-pagination-padding-y: 0.75rem; + --bs-pagination-font-size: 1.25rem; + --bs-pagination-border-radius: var(--bs-border-radius-lg); +} + +.pagination-sm { + --bs-pagination-padding-x: 0.5rem; + --bs-pagination-padding-y: 0.25rem; + --bs-pagination-font-size: 0.875rem; + --bs-pagination-border-radius: var(--bs-border-radius-sm); +} + +.badge { + --bs-badge-padding-x: 0.65em; + --bs-badge-padding-y: 0.35em; + --bs-badge-font-size: 0.75em; + --bs-badge-font-weight: 700; + --bs-badge-color: #fff; + --bs-badge-border-radius: var(--bs-border-radius); + display: inline-block; + padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x); + font-size: var(--bs-badge-font-size); + font-weight: var(--bs-badge-font-weight); + line-height: 1; + color: var(--bs-badge-color); + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: var(--bs-badge-border-radius); +} +.badge:empty { + display: none; +} + +.btn .badge { + position: relative; + top: -1px; +} + +.alert { + --bs-alert-bg: transparent; + --bs-alert-padding-x: 1rem; + --bs-alert-padding-y: 1rem; + --bs-alert-margin-bottom: 1rem; + --bs-alert-color: inherit; + --bs-alert-border-color: transparent; + --bs-alert-border: var(--bs-border-width) solid var(--bs-alert-border-color); + --bs-alert-border-radius: var(--bs-border-radius); + --bs-alert-link-color: inherit; + position: relative; + padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x); + margin-bottom: var(--bs-alert-margin-bottom); + color: var(--bs-alert-color); + background-color: var(--bs-alert-bg); + border: var(--bs-alert-border); + border-radius: var(--bs-alert-border-radius); +} + +.alert-heading { + color: inherit; +} + +.alert-link { + font-weight: 700; + color: var(--bs-alert-link-color); +} + +.alert-dismissible { + padding-right: 3rem; +} +.alert-dismissible .btn-close { + position: absolute; + top: 0; + right: 0; + z-index: 2; + padding: 1.25rem 1rem; +} + +.alert-primary { + --bs-alert-color: var(--bs-primary-text-emphasis); + --bs-alert-bg: var(--bs-primary-bg-subtle); + --bs-alert-border-color: var(--bs-primary-border-subtle); + --bs-alert-link-color: var(--bs-primary-text-emphasis); +} + +.alert-secondary { + --bs-alert-color: var(--bs-secondary-text-emphasis); + --bs-alert-bg: var(--bs-secondary-bg-subtle); + --bs-alert-border-color: var(--bs-secondary-border-subtle); + --bs-alert-link-color: var(--bs-secondary-text-emphasis); +} + +.alert-success { + --bs-alert-color: var(--bs-success-text-emphasis); + --bs-alert-bg: var(--bs-success-bg-subtle); + --bs-alert-border-color: var(--bs-success-border-subtle); + --bs-alert-link-color: var(--bs-success-text-emphasis); +} + +.alert-info { + --bs-alert-color: var(--bs-info-text-emphasis); + --bs-alert-bg: var(--bs-info-bg-subtle); + --bs-alert-border-color: var(--bs-info-border-subtle); + --bs-alert-link-color: var(--bs-info-text-emphasis); +} + +.alert-warning { + --bs-alert-color: var(--bs-warning-text-emphasis); + --bs-alert-bg: var(--bs-warning-bg-subtle); + --bs-alert-border-color: var(--bs-warning-border-subtle); + --bs-alert-link-color: var(--bs-warning-text-emphasis); +} + +.alert-danger { + --bs-alert-color: var(--bs-danger-text-emphasis); + --bs-alert-bg: var(--bs-danger-bg-subtle); + --bs-alert-border-color: var(--bs-danger-border-subtle); + --bs-alert-link-color: var(--bs-danger-text-emphasis); +} + +.alert-light { + --bs-alert-color: var(--bs-light-text-emphasis); + --bs-alert-bg: var(--bs-light-bg-subtle); + --bs-alert-border-color: var(--bs-light-border-subtle); + --bs-alert-link-color: var(--bs-light-text-emphasis); +} + +.alert-dark { + --bs-alert-color: var(--bs-dark-text-emphasis); + --bs-alert-bg: var(--bs-dark-bg-subtle); + --bs-alert-border-color: var(--bs-dark-border-subtle); + --bs-alert-link-color: var(--bs-dark-text-emphasis); +} + +@keyframes progress-bar-stripes { + 0% { + background-position-x: 1rem; + } +} +.progress, +.progress-stacked { + --bs-progress-height: 1rem; + --bs-progress-font-size: 0.75rem; + --bs-progress-bg: var(--bs-secondary-bg); + --bs-progress-border-radius: var(--bs-border-radius); + --bs-progress-box-shadow: var(--bs-box-shadow-inset); + --bs-progress-bar-color: #fff; + --bs-progress-bar-bg: #3459e6; + --bs-progress-bar-transition: width 0.6s ease; + display: flex; + height: var(--bs-progress-height); + overflow: hidden; + font-size: var(--bs-progress-font-size); + background-color: var(--bs-progress-bg); + border-radius: var(--bs-progress-border-radius); + box-shadow: var(--bs-progress-box-shadow); +} + +.progress-bar { + display: flex; + flex-direction: column; + justify-content: center; + overflow: hidden; + color: var(--bs-progress-bar-color); + text-align: center; + white-space: nowrap; + background-color: var(--bs-progress-bar-bg); + transition: var(--bs-progress-bar-transition); +} +@media (prefers-reduced-motion: reduce) { + .progress-bar { + transition: none; + } +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: var(--bs-progress-height) var(--bs-progress-height); +} + +.progress-stacked > .progress { + overflow: visible; +} + +.progress-stacked > .progress > .progress-bar { + width: 100%; +} + +.progress-bar-animated { + animation: 1s linear infinite progress-bar-stripes; +} +@media (prefers-reduced-motion: reduce) { + .progress-bar-animated { + animation: none; + } +} + +.list-group { + --bs-list-group-color: var(--bs-body-color); + --bs-list-group-bg: var(--bs-body-bg); + --bs-list-group-border-color: var(--bs-border-color); + --bs-list-group-border-width: var(--bs-border-width); + --bs-list-group-border-radius: var(--bs-border-radius); + --bs-list-group-item-padding-x: 1.5rem; + --bs-list-group-item-padding-y: 1rem; + --bs-list-group-action-color: var(--bs-secondary-color); + --bs-list-group-action-hover-color: var(--bs-emphasis-color); + --bs-list-group-action-hover-bg: var(--bs-tertiary-bg); + --bs-list-group-action-active-color: var(--bs-body-color); + --bs-list-group-action-active-bg: var(--bs-secondary-bg); + --bs-list-group-disabled-color: var(--bs-secondary-color); + --bs-list-group-disabled-bg: var(--bs-body-bg); + --bs-list-group-active-color: #fff; + --bs-list-group-active-bg: #3459e6; + --bs-list-group-active-border-color: #3459e6; + display: flex; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + border-radius: var(--bs-list-group-border-radius); +} + +.list-group-numbered { + list-style-type: none; + counter-reset: section; +} +.list-group-numbered > .list-group-item::before { + content: counters(section, ".") ". "; + counter-increment: section; +} + +.list-group-item-action { + width: 100%; + color: var(--bs-list-group-action-color); + text-align: inherit; +} +.list-group-item-action:hover, .list-group-item-action:focus { + z-index: 1; + color: var(--bs-list-group-action-hover-color); + text-decoration: none; + background-color: var(--bs-list-group-action-hover-bg); +} +.list-group-item-action:active { + color: var(--bs-list-group-action-active-color); + background-color: var(--bs-list-group-action-active-bg); +} + +.list-group-item { + position: relative; + display: block; + padding: var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x); + color: var(--bs-list-group-color); + text-decoration: none; + background-color: var(--bs-list-group-bg); + border: var(--bs-list-group-border-width) solid var(--bs-list-group-border-color); +} +.list-group-item:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.list-group-item:last-child { + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit; +} +.list-group-item.disabled, .list-group-item:disabled { + color: var(--bs-list-group-disabled-color); + pointer-events: none; + background-color: var(--bs-list-group-disabled-bg); +} +.list-group-item.active { + z-index: 2; + color: var(--bs-list-group-active-color); + background-color: var(--bs-list-group-active-bg); + border-color: var(--bs-list-group-active-border-color); +} +.list-group-item + .list-group-item { + border-top-width: 0; +} +.list-group-item + .list-group-item.active { + margin-top: calc(-1 * var(--bs-list-group-border-width)); + border-top-width: var(--bs-list-group-border-width); +} + +.list-group-horizontal { + flex-direction: row; +} +.list-group-horizontal > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; +} +.list-group-horizontal > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; +} +.list-group-horizontal > .list-group-item.active { + margin-top: 0; +} +.list-group-horizontal > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; +} +.list-group-horizontal > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); +} + +@media (min-width: 576px) { + .list-group-horizontal-sm { + flex-direction: row; + } + .list-group-horizontal-sm > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; + } + .list-group-horizontal-sm > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; + } + .list-group-horizontal-sm > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); + } +} +@media (min-width: 768px) { + .list-group-horizontal-md { + flex-direction: row; + } + .list-group-horizontal-md > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; + } + .list-group-horizontal-md > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; + } + .list-group-horizontal-md > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); + } +} +@media (min-width: 992px) { + .list-group-horizontal-lg { + flex-direction: row; + } + .list-group-horizontal-lg > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; + } + .list-group-horizontal-lg > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; + } + .list-group-horizontal-lg > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); + } +} +@media (min-width: 1200px) { + .list-group-horizontal-xl { + flex-direction: row; + } + .list-group-horizontal-xl > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; + } + .list-group-horizontal-xl > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; + } + .list-group-horizontal-xl > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); + } +} +@media (min-width: 1400px) { + .list-group-horizontal-xxl { + flex-direction: row; + } + .list-group-horizontal-xxl > .list-group-item:first-child:not(:last-child) { + border-bottom-left-radius: var(--bs-list-group-border-radius); + border-top-right-radius: 0; + } + .list-group-horizontal-xxl > .list-group-item:last-child:not(:first-child) { + border-top-right-radius: var(--bs-list-group-border-radius); + border-bottom-left-radius: 0; + } + .list-group-horizontal-xxl > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-xxl > .list-group-item + .list-group-item { + border-top-width: var(--bs-list-group-border-width); + border-left-width: 0; + } + .list-group-horizontal-xxl > .list-group-item + .list-group-item.active { + margin-left: calc(-1 * var(--bs-list-group-border-width)); + border-left-width: var(--bs-list-group-border-width); + } +} +.list-group-flush { + border-radius: 0; +} +.list-group-flush > .list-group-item { + border-width: 0 0 var(--bs-list-group-border-width); +} +.list-group-flush > .list-group-item:last-child { + border-bottom-width: 0; +} + +.list-group-item-primary { + --bs-list-group-color: var(--bs-primary-text-emphasis); + --bs-list-group-bg: var(--bs-primary-bg-subtle); + --bs-list-group-border-color: var(--bs-primary-border-subtle); + --bs-list-group-action-hover-color: var(--bs-emphasis-color); + --bs-list-group-action-hover-bg: var(--bs-primary-border-subtle); + --bs-list-group-action-active-color: var(--bs-emphasis-color); + --bs-list-group-action-active-bg: var(--bs-primary-border-subtle); + --bs-list-group-active-color: var(--bs-primary-bg-subtle); + --bs-list-group-active-bg: var(--bs-primary-text-emphasis); + --bs-list-group-active-border-color: var(--bs-primary-text-emphasis); +} + +.list-group-item-secondary { + --bs-list-group-color: var(--bs-secondary-text-emphasis); + --bs-list-group-bg: var(--bs-secondary-bg-subtle); + --bs-list-group-border-color: var(--bs-secondary-border-subtle); + --bs-list-group-action-hover-color: var(--bs-emphasis-color); + --bs-list-group-action-hover-bg: var(--bs-secondary-border-subtle); + --bs-list-group-action-active-color: var(--bs-emphasis-color); + --bs-list-group-action-active-bg: var(--bs-secondary-border-subtle); + --bs-list-group-active-color: var(--bs-secondary-bg-subtle); + --bs-list-group-active-bg: var(--bs-secondary-text-emphasis); + --bs-list-group-active-border-color: var(--bs-secondary-text-emphasis); +} + +.list-group-item-success { + --bs-list-group-color: var(--bs-success-text-emphasis); + --bs-list-group-bg: var(--bs-success-bg-subtle); + --bs-list-group-border-color: var(--bs-success-border-subtle); + --bs-list-group-action-hover-color: var(--bs-emphasis-color); + --bs-list-group-action-hover-bg: var(--bs-success-border-subtle); + --bs-list-group-action-active-color: var(--bs-emphasis-color); + --bs-list-group-action-active-bg: var(--bs-success-border-subtle); + --bs-list-group-active-color: var(--bs-success-bg-subtle); + --bs-list-group-active-bg: var(--bs-success-text-emphasis); + --bs-list-group-active-border-color: var(--bs-success-text-emphasis); +} + +.list-group-item-info { + --bs-list-group-color: var(--bs-info-text-emphasis); + --bs-list-group-bg: var(--bs-info-bg-subtle); + --bs-list-group-border-color: var(--bs-info-border-subtle); + --bs-list-group-action-hover-color: var(--bs-emphasis-color); + --bs-list-group-action-hover-bg: var(--bs-info-border-subtle); + --bs-list-group-action-active-color: var(--bs-emphasis-color); + --bs-list-group-action-active-bg: var(--bs-info-border-subtle); + --bs-list-group-active-color: var(--bs-info-bg-subtle); + --bs-list-group-active-bg: var(--bs-info-text-emphasis); + --bs-list-group-active-border-color: var(--bs-info-text-emphasis); +} + +.list-group-item-warning { + --bs-list-group-color: var(--bs-warning-text-emphasis); + --bs-list-group-bg: var(--bs-warning-bg-subtle); + --bs-list-group-border-color: var(--bs-warning-border-subtle); + --bs-list-group-action-hover-color: var(--bs-emphasis-color); + --bs-list-group-action-hover-bg: var(--bs-warning-border-subtle); + --bs-list-group-action-active-color: var(--bs-emphasis-color); + --bs-list-group-action-active-bg: var(--bs-warning-border-subtle); + --bs-list-group-active-color: var(--bs-warning-bg-subtle); + --bs-list-group-active-bg: var(--bs-warning-text-emphasis); + --bs-list-group-active-border-color: var(--bs-warning-text-emphasis); +} + +.list-group-item-danger { + --bs-list-group-color: var(--bs-danger-text-emphasis); + --bs-list-group-bg: var(--bs-danger-bg-subtle); + --bs-list-group-border-color: var(--bs-danger-border-subtle); + --bs-list-group-action-hover-color: var(--bs-emphasis-color); + --bs-list-group-action-hover-bg: var(--bs-danger-border-subtle); + --bs-list-group-action-active-color: var(--bs-emphasis-color); + --bs-list-group-action-active-bg: var(--bs-danger-border-subtle); + --bs-list-group-active-color: var(--bs-danger-bg-subtle); + --bs-list-group-active-bg: var(--bs-danger-text-emphasis); + --bs-list-group-active-border-color: var(--bs-danger-text-emphasis); +} + +.list-group-item-light { + --bs-list-group-color: var(--bs-light-text-emphasis); + --bs-list-group-bg: var(--bs-light-bg-subtle); + --bs-list-group-border-color: var(--bs-light-border-subtle); + --bs-list-group-action-hover-color: var(--bs-emphasis-color); + --bs-list-group-action-hover-bg: var(--bs-light-border-subtle); + --bs-list-group-action-active-color: var(--bs-emphasis-color); + --bs-list-group-action-active-bg: var(--bs-light-border-subtle); + --bs-list-group-active-color: var(--bs-light-bg-subtle); + --bs-list-group-active-bg: var(--bs-light-text-emphasis); + --bs-list-group-active-border-color: var(--bs-light-text-emphasis); +} + +.list-group-item-dark { + --bs-list-group-color: var(--bs-dark-text-emphasis); + --bs-list-group-bg: var(--bs-dark-bg-subtle); + --bs-list-group-border-color: var(--bs-dark-border-subtle); + --bs-list-group-action-hover-color: var(--bs-emphasis-color); + --bs-list-group-action-hover-bg: var(--bs-dark-border-subtle); + --bs-list-group-action-active-color: var(--bs-emphasis-color); + --bs-list-group-action-active-bg: var(--bs-dark-border-subtle); + --bs-list-group-active-color: var(--bs-dark-bg-subtle); + --bs-list-group-active-bg: var(--bs-dark-text-emphasis); + --bs-list-group-active-border-color: var(--bs-dark-text-emphasis); +} + +.btn-close { + --bs-btn-close-color: #000; + --bs-btn-close-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e"); + --bs-btn-close-opacity: 0.5; + --bs-btn-close-hover-opacity: 0.75; + --bs-btn-close-focus-shadow: 0 0 0 0.25rem rgba(52, 89, 230, 0.25); + --bs-btn-close-focus-opacity: 1; + --bs-btn-close-disabled-opacity: 0.25; + --bs-btn-close-white-filter: invert(1) grayscale(100%) brightness(200%); + box-sizing: content-box; + width: 1em; + height: 1em; + padding: 0.25em 0.25em; + color: var(--bs-btn-close-color); + background: transparent var(--bs-btn-close-bg) center/1em auto no-repeat; + border: 0; + border-radius: 0.375rem; + opacity: var(--bs-btn-close-opacity); +} +.btn-close:hover { + color: var(--bs-btn-close-color); + text-decoration: none; + opacity: var(--bs-btn-close-hover-opacity); +} +.btn-close:focus { + outline: 0; + box-shadow: var(--bs-btn-close-focus-shadow); + opacity: var(--bs-btn-close-focus-opacity); +} +.btn-close:disabled, .btn-close.disabled { + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + opacity: var(--bs-btn-close-disabled-opacity); +} + +.btn-close-white { + filter: var(--bs-btn-close-white-filter); +} + +[data-bs-theme=dark] .btn-close { + filter: var(--bs-btn-close-white-filter); +} + +.toast { + --bs-toast-zindex: 1090; + --bs-toast-padding-x: 0.75rem; + --bs-toast-padding-y: 0.5rem; + --bs-toast-spacing: 1.5rem; + --bs-toast-max-width: 350px; + --bs-toast-font-size: 0.875rem; + --bs-toast-color: ; + --bs-toast-bg: rgba(var(--bs-body-bg-rgb), 0.85); + --bs-toast-border-width: var(--bs-border-width); + --bs-toast-border-color: var(--bs-border-color-translucent); + --bs-toast-border-radius: var(--bs-border-radius); + --bs-toast-box-shadow: var(--bs-box-shadow); + --bs-toast-header-color: var(--bs-primary-color); + --bs-toast-header-bg: rgba(var(--bs-body-bg-rgb), 0.85); + --bs-toast-header-border-color: var(--bs-border-color-translucent); + width: var(--bs-toast-max-width); + max-width: 100%; + font-size: var(--bs-toast-font-size); + color: var(--bs-toast-color); + pointer-events: auto; + background-color: var(--bs-toast-bg); + background-clip: padding-box; + border: var(--bs-toast-border-width) solid var(--bs-toast-border-color); + box-shadow: var(--bs-toast-box-shadow); + border-radius: var(--bs-toast-border-radius); +} +.toast.showing { + opacity: 0; +} +.toast:not(.show) { + display: none; +} + +.toast-container { + --bs-toast-zindex: 1090; + position: absolute; + z-index: var(--bs-toast-zindex); + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; + max-width: 100%; + pointer-events: none; +} +.toast-container > :not(:last-child) { + margin-bottom: var(--bs-toast-spacing); +} + +.toast-header { + display: flex; + align-items: center; + padding: var(--bs-toast-padding-y) var(--bs-toast-padding-x); + color: var(--bs-toast-header-color); + background-color: var(--bs-toast-header-bg); + background-clip: padding-box; + border-bottom: var(--bs-toast-border-width) solid var(--bs-toast-header-border-color); + border-top-left-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width)); + border-top-right-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width)); +} +.toast-header .btn-close { + margin-right: calc(-0.5 * var(--bs-toast-padding-x)); + margin-left: var(--bs-toast-padding-x); +} + +.toast-body { + padding: var(--bs-toast-padding-x); + word-wrap: break-word; +} + +.modal { + --bs-modal-zindex: 1055; + --bs-modal-width: 500px; + --bs-modal-padding: 1rem; + --bs-modal-margin: 0.5rem; + --bs-modal-color: ; + --bs-modal-bg: var(--bs-body-bg); + --bs-modal-border-color: var(--bs-border-color-translucent); + --bs-modal-border-width: var(--bs-border-width); + --bs-modal-border-radius: var(--bs-border-radius-lg); + --bs-modal-box-shadow: var(--bs-box-shadow-sm); + --bs-modal-inner-border-radius: calc(var(--bs-border-radius-lg) - (var(--bs-border-width))); + --bs-modal-header-padding-x: 1rem; + --bs-modal-header-padding-y: 1rem; + --bs-modal-header-padding: 1rem 1rem; + --bs-modal-header-border-color: var(--bs-border-color); + --bs-modal-header-border-width: 0; + --bs-modal-title-line-height: 1.5; + --bs-modal-footer-gap: 0.5rem; + --bs-modal-footer-bg: ; + --bs-modal-footer-border-color: var(--bs-border-color); + --bs-modal-footer-border-width: 0; + position: fixed; + top: 0; + left: 0; + z-index: var(--bs-modal-zindex); + display: none; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + outline: 0; +} + +.modal-dialog { + position: relative; + width: auto; + margin: var(--bs-modal-margin); + pointer-events: none; +} +.modal.fade .modal-dialog { + transition: transform 0.3s ease-out; + transform: translate(0, -50px); +} +@media (prefers-reduced-motion: reduce) { + .modal.fade .modal-dialog { + transition: none; + } +} +.modal.show .modal-dialog { + transform: none; +} +.modal.modal-static .modal-dialog { + transform: scale(1.02); +} + +.modal-dialog-scrollable { + height: calc(100% - var(--bs-modal-margin) * 2); +} +.modal-dialog-scrollable .modal-content { + max-height: 100%; + overflow: hidden; +} +.modal-dialog-scrollable .modal-body { + overflow-y: auto; +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - var(--bs-modal-margin) * 2); +} + +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; + color: var(--bs-modal-color); + pointer-events: auto; + background-color: var(--bs-modal-bg); + background-clip: padding-box; + border: var(--bs-modal-border-width) solid var(--bs-modal-border-color); + border-radius: var(--bs-modal-border-radius); + box-shadow: var(--bs-modal-box-shadow); + outline: 0; +} + +.modal-backdrop { + --bs-backdrop-zindex: 1050; + --bs-backdrop-bg: #000; + --bs-backdrop-opacity: 0.5; + position: fixed; + top: 0; + left: 0; + z-index: var(--bs-backdrop-zindex); + width: 100vw; + height: 100vh; + background-color: var(--bs-backdrop-bg); +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop.show { + opacity: var(--bs-backdrop-opacity); +} + +.modal-header { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: space-between; + padding: var(--bs-modal-header-padding); + border-bottom: var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color); + border-top-left-radius: var(--bs-modal-inner-border-radius); + border-top-right-radius: var(--bs-modal-inner-border-radius); +} +.modal-header .btn-close { + padding: calc(var(--bs-modal-header-padding-y) * 0.5) calc(var(--bs-modal-header-padding-x) * 0.5); + margin: calc(-0.5 * var(--bs-modal-header-padding-y)) calc(-0.5 * var(--bs-modal-header-padding-x)) calc(-0.5 * var(--bs-modal-header-padding-y)) auto; +} + +.modal-title { + margin-bottom: 0; + line-height: var(--bs-modal-title-line-height); +} + +.modal-body { + position: relative; + flex: 1 1 auto; + padding: var(--bs-modal-padding); +} + +.modal-footer { + display: flex; + flex-shrink: 0; + flex-wrap: wrap; + align-items: center; + justify-content: flex-end; + padding: calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * 0.5); + background-color: var(--bs-modal-footer-bg); + border-top: var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color); + border-bottom-right-radius: var(--bs-modal-inner-border-radius); + border-bottom-left-radius: var(--bs-modal-inner-border-radius); +} +.modal-footer > * { + margin: calc(var(--bs-modal-footer-gap) * 0.5); +} + +@media (min-width: 576px) { + .modal { + --bs-modal-margin: 1.75rem; + --bs-modal-box-shadow: var(--bs-box-shadow); + } + .modal-dialog { + max-width: var(--bs-modal-width); + margin-right: auto; + margin-left: auto; + } + .modal-sm { + --bs-modal-width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg, + .modal-xl { + --bs-modal-width: 800px; + } +} +@media (min-width: 1200px) { + .modal-xl { + --bs-modal-width: 1140px; + } +} +.modal-fullscreen { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; +} +.modal-fullscreen .modal-content { + height: 100%; + border: 0; + border-radius: 0; +} +.modal-fullscreen .modal-header, +.modal-fullscreen .modal-footer { + border-radius: 0; +} +.modal-fullscreen .modal-body { + overflow-y: auto; +} + +@media (max-width: 575.98px) { + .modal-fullscreen-sm-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-sm-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-sm-down .modal-header, + .modal-fullscreen-sm-down .modal-footer { + border-radius: 0; + } + .modal-fullscreen-sm-down .modal-body { + overflow-y: auto; + } +} +@media (max-width: 767.98px) { + .modal-fullscreen-md-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-md-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-md-down .modal-header, + .modal-fullscreen-md-down .modal-footer { + border-radius: 0; + } + .modal-fullscreen-md-down .modal-body { + overflow-y: auto; + } +} +@media (max-width: 991.98px) { + .modal-fullscreen-lg-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-lg-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-lg-down .modal-header, + .modal-fullscreen-lg-down .modal-footer { + border-radius: 0; + } + .modal-fullscreen-lg-down .modal-body { + overflow-y: auto; + } +} +@media (max-width: 1199.98px) { + .modal-fullscreen-xl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-xl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-xl-down .modal-header, + .modal-fullscreen-xl-down .modal-footer { + border-radius: 0; + } + .modal-fullscreen-xl-down .modal-body { + overflow-y: auto; + } +} +@media (max-width: 1399.98px) { + .modal-fullscreen-xxl-down { + width: 100vw; + max-width: none; + height: 100%; + margin: 0; + } + .modal-fullscreen-xxl-down .modal-content { + height: 100%; + border: 0; + border-radius: 0; + } + .modal-fullscreen-xxl-down .modal-header, + .modal-fullscreen-xxl-down .modal-footer { + border-radius: 0; + } + .modal-fullscreen-xxl-down .modal-body { + overflow-y: auto; + } +} +.tooltip { + --bs-tooltip-zindex: 1080; + --bs-tooltip-max-width: 200px; + --bs-tooltip-padding-x: 0.5rem; + --bs-tooltip-padding-y: 0.25rem; + --bs-tooltip-margin: ; + --bs-tooltip-font-size: 0.875rem; + --bs-tooltip-color: var(--bs-body-bg); + --bs-tooltip-bg: var(--bs-emphasis-color); + --bs-tooltip-border-radius: var(--bs-border-radius); + --bs-tooltip-opacity: 0.9; + --bs-tooltip-arrow-width: 0.8rem; + --bs-tooltip-arrow-height: 0.4rem; + z-index: var(--bs-tooltip-zindex); + display: block; + margin: var(--bs-tooltip-margin); + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + white-space: normal; + word-spacing: normal; + line-break: auto; + font-size: var(--bs-tooltip-font-size); + word-wrap: break-word; + opacity: 0; +} +.tooltip.show { + opacity: var(--bs-tooltip-opacity); +} +.tooltip .tooltip-arrow { + display: block; + width: var(--bs-tooltip-arrow-width); + height: var(--bs-tooltip-arrow-height); +} +.tooltip .tooltip-arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow { + bottom: calc(-1 * var(--bs-tooltip-arrow-height)); +} +.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before { + top: -1px; + border-width: var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0; + border-top-color: var(--bs-tooltip-bg); +} + +/* rtl:begin:ignore */ +.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow { + left: calc(-1 * var(--bs-tooltip-arrow-height)); + width: var(--bs-tooltip-arrow-height); + height: var(--bs-tooltip-arrow-width); +} +.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before { + right: -1px; + border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0; + border-right-color: var(--bs-tooltip-bg); +} + +/* rtl:end:ignore */ +.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow { + top: calc(-1 * var(--bs-tooltip-arrow-height)); +} +.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before { + bottom: -1px; + border-width: 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height); + border-bottom-color: var(--bs-tooltip-bg); +} + +/* rtl:begin:ignore */ +.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow { + right: calc(-1 * var(--bs-tooltip-arrow-height)); + width: var(--bs-tooltip-arrow-height); + height: var(--bs-tooltip-arrow-width); +} +.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before { + left: -1px; + border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height); + border-left-color: var(--bs-tooltip-bg); +} + +/* rtl:end:ignore */ +.tooltip-inner { + max-width: var(--bs-tooltip-max-width); + padding: var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x); + color: var(--bs-tooltip-color); + text-align: center; + background-color: var(--bs-tooltip-bg); + border-radius: var(--bs-tooltip-border-radius); +} + +.popover { + --bs-popover-zindex: 1070; + --bs-popover-max-width: 276px; + --bs-popover-font-size: 0.875rem; + --bs-popover-bg: var(--bs-body-bg); + --bs-popover-border-width: var(--bs-border-width); + --bs-popover-border-color: var(--bs-border-color-translucent); + --bs-popover-border-radius: var(--bs-border-radius-lg); + --bs-popover-inner-border-radius: calc(var(--bs-border-radius-lg) - var(--bs-border-width)); + --bs-popover-box-shadow: var(--bs-box-shadow); + --bs-popover-header-padding-x: 1rem; + --bs-popover-header-padding-y: 0.5rem; + --bs-popover-header-font-size: 1rem; + --bs-popover-header-color: var(--bs-primary-color); + --bs-popover-header-bg: var(--bs-secondary-bg); + --bs-popover-body-padding-x: 1rem; + --bs-popover-body-padding-y: 1rem; + --bs-popover-body-color: var(--bs-body-color); + --bs-popover-arrow-width: 1rem; + --bs-popover-arrow-height: 0.5rem; + --bs-popover-arrow-border: var(--bs-popover-border-color); + z-index: var(--bs-popover-zindex); + display: block; + max-width: var(--bs-popover-max-width); + font-family: var(--bs-font-sans-serif); + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + white-space: normal; + word-spacing: normal; + line-break: auto; + font-size: var(--bs-popover-font-size); + word-wrap: break-word; + background-color: var(--bs-popover-bg); + background-clip: padding-box; + border: var(--bs-popover-border-width) solid var(--bs-popover-border-color); + border-radius: var(--bs-popover-border-radius); + box-shadow: var(--bs-popover-box-shadow); +} +.popover .popover-arrow { + display: block; + width: var(--bs-popover-arrow-width); + height: var(--bs-popover-arrow-height); +} +.popover .popover-arrow::before, .popover .popover-arrow::after { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid; + border-width: 0; +} + +.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow { + bottom: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width)); +} +.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after { + border-width: var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0; +} +.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before { + bottom: 0; + border-top-color: var(--bs-popover-arrow-border); +} +.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after { + bottom: var(--bs-popover-border-width); + border-top-color: var(--bs-popover-bg); +} + +/* rtl:begin:ignore */ +.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow { + left: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width)); + width: var(--bs-popover-arrow-height); + height: var(--bs-popover-arrow-width); +} +.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after { + border-width: calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0; +} +.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before { + left: 0; + border-right-color: var(--bs-popover-arrow-border); +} +.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after { + left: var(--bs-popover-border-width); + border-right-color: var(--bs-popover-bg); +} + +/* rtl:end:ignore */ +.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow { + top: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width)); +} +.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after { + border-width: 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height); +} +.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before { + top: 0; + border-bottom-color: var(--bs-popover-arrow-border); +} +.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after { + top: var(--bs-popover-border-width); + border-bottom-color: var(--bs-popover-bg); +} +.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: var(--bs-popover-arrow-width); + margin-left: calc(-0.5 * var(--bs-popover-arrow-width)); + content: ""; + border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-header-bg); +} + +/* rtl:begin:ignore */ +.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow { + right: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width)); + width: var(--bs-popover-arrow-height); + height: var(--bs-popover-arrow-width); +} +.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after { + border-width: calc(var(--bs-popover-arrow-width) * 0.5) 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height); +} +.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before { + right: 0; + border-left-color: var(--bs-popover-arrow-border); +} +.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after { + right: var(--bs-popover-border-width); + border-left-color: var(--bs-popover-bg); +} + +/* rtl:end:ignore */ +.popover-header { + padding: var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x); + margin-bottom: 0; + font-size: var(--bs-popover-header-font-size); + color: var(--bs-popover-header-color); + background-color: var(--bs-popover-header-bg); + border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-border-color); + border-top-left-radius: var(--bs-popover-inner-border-radius); + border-top-right-radius: var(--bs-popover-inner-border-radius); +} +.popover-header:empty { + display: none; +} + +.popover-body { + padding: var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x); + color: var(--bs-popover-body-color); +} + +.carousel { + position: relative; +} + +.carousel.pointer-event { + touch-action: pan-y; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner::after { + display: block; + clear: both; + content: ""; +} + +.carousel-item { + position: relative; + display: none; + float: left; + width: 100%; + margin-right: -100%; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transition: transform 0.6s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .carousel-item { + transition: none; + } +} + +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: block; +} + +.carousel-item-next:not(.carousel-item-start), +.active.carousel-item-end { + transform: translateX(100%); +} + +.carousel-item-prev:not(.carousel-item-end), +.active.carousel-item-start { + transform: translateX(-100%); +} + +.carousel-fade .carousel-item { + opacity: 0; + transition-property: opacity; + transform: none; +} +.carousel-fade .carousel-item.active, +.carousel-fade .carousel-item-next.carousel-item-start, +.carousel-fade .carousel-item-prev.carousel-item-end { + z-index: 1; + opacity: 1; +} +.carousel-fade .active.carousel-item-start, +.carousel-fade .active.carousel-item-end { + z-index: 0; + opacity: 0; + transition: opacity 0s 0.6s; +} +@media (prefers-reduced-motion: reduce) { + .carousel-fade .active.carousel-item-start, + .carousel-fade .active.carousel-item-end { + transition: none; + } +} + +.carousel-control-prev, +.carousel-control-next { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + width: 15%; + padding: 0; + color: #fff; + text-align: center; + background: none; + border: 0; + opacity: 0.5; + transition: opacity 0.15s ease; +} +@media (prefers-reduced-motion: reduce) { + .carousel-control-prev, + .carousel-control-next { + transition: none; + } +} +.carousel-control-prev:hover, .carousel-control-prev:focus, +.carousel-control-next:hover, +.carousel-control-next:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: 0.9; +} + +.carousel-control-prev { + left: 0; +} + +.carousel-control-next { + right: 0; +} + +.carousel-control-prev-icon, +.carousel-control-next-icon { + display: inline-block; + width: 2rem; + height: 2rem; + background-repeat: no-repeat; + background-position: 50%; + background-size: 100% 100%; +} + +/* rtl:options: { + "autoRename": true, + "stringMap":[ { + "name" : "prev-next", + "search" : "prev", + "replace" : "next" + } ] +} */ +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e"); +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e"); +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 2; + display: flex; + justify-content: center; + padding: 0; + margin-right: 15%; + margin-bottom: 1rem; + margin-left: 15%; +} +.carousel-indicators [data-bs-target] { + box-sizing: content-box; + flex: 0 1 auto; + width: 30px; + height: 3px; + padding: 0; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + cursor: pointer; + background-color: #fff; + background-clip: padding-box; + border: 0; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + opacity: 0.5; + transition: opacity 0.6s ease; +} +@media (prefers-reduced-motion: reduce) { + .carousel-indicators [data-bs-target] { + transition: none; + } +} +.carousel-indicators .active { + opacity: 1; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 1.25rem; + left: 15%; + padding-top: 1.25rem; + padding-bottom: 1.25rem; + color: #fff; + text-align: center; +} + +.carousel-dark .carousel-control-prev-icon, +.carousel-dark .carousel-control-next-icon { + filter: invert(1) grayscale(100); +} +.carousel-dark .carousel-indicators [data-bs-target] { + background-color: #000; +} +.carousel-dark .carousel-caption { + color: #000; +} + +[data-bs-theme=dark] .carousel .carousel-control-prev-icon, +[data-bs-theme=dark] .carousel .carousel-control-next-icon, [data-bs-theme=dark].carousel .carousel-control-prev-icon, +[data-bs-theme=dark].carousel .carousel-control-next-icon { + filter: invert(1) grayscale(100); +} +[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target], [data-bs-theme=dark].carousel .carousel-indicators [data-bs-target] { + background-color: #000; +} +[data-bs-theme=dark] .carousel .carousel-caption, [data-bs-theme=dark].carousel .carousel-caption { + color: #000; +} + +.spinner-grow, +.spinner-border { + display: inline-block; + width: var(--bs-spinner-width); + height: var(--bs-spinner-height); + vertical-align: var(--bs-spinner-vertical-align); + border-radius: 50%; + animation: var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name); +} + +@keyframes spinner-border { + to { + transform: rotate(360deg) /* rtl:ignore */; + } +} +.spinner-border { + --bs-spinner-width: 2rem; + --bs-spinner-height: 2rem; + --bs-spinner-vertical-align: -0.125em; + --bs-spinner-border-width: 0.25em; + --bs-spinner-animation-speed: 0.75s; + --bs-spinner-animation-name: spinner-border; + border: var(--bs-spinner-border-width) solid currentcolor; + border-right-color: transparent; +} + +.spinner-border-sm { + --bs-spinner-width: 1rem; + --bs-spinner-height: 1rem; + --bs-spinner-border-width: 0.2em; +} + +@keyframes spinner-grow { + 0% { + transform: scale(0); + } + 50% { + opacity: 1; + transform: none; + } +} +.spinner-grow { + --bs-spinner-width: 2rem; + --bs-spinner-height: 2rem; + --bs-spinner-vertical-align: -0.125em; + --bs-spinner-animation-speed: 0.75s; + --bs-spinner-animation-name: spinner-grow; + background-color: currentcolor; + opacity: 0; +} + +.spinner-grow-sm { + --bs-spinner-width: 1rem; + --bs-spinner-height: 1rem; +} + +@media (prefers-reduced-motion: reduce) { + .spinner-border, + .spinner-grow { + --bs-spinner-animation-speed: 1.5s; + } +} +.offcanvas, .offcanvas-xxl, .offcanvas-xl, .offcanvas-lg, .offcanvas-md, .offcanvas-sm { + --bs-offcanvas-zindex: 1045; + --bs-offcanvas-width: 400px; + --bs-offcanvas-height: 30vh; + --bs-offcanvas-padding-x: 1rem; + --bs-offcanvas-padding-y: 1rem; + --bs-offcanvas-color: var(--bs-body-color); + --bs-offcanvas-bg: var(--bs-body-bg); + --bs-offcanvas-border-width: var(--bs-border-width); + --bs-offcanvas-border-color: var(--bs-border-color-translucent); + --bs-offcanvas-box-shadow: var(--bs-box-shadow-sm); + --bs-offcanvas-transition: transform 0.3s ease-in-out; + --bs-offcanvas-title-line-height: 1.5; +} + +@media (max-width: 575.98px) { + .offcanvas-sm { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + box-shadow: var(--bs-offcanvas-box-shadow); + transition: var(--bs-offcanvas-transition); + } +} +@media (max-width: 575.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-sm { + transition: none; + } +} +@media (max-width: 575.98px) { + .offcanvas-sm.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); + } + .offcanvas-sm.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); + } + .offcanvas-sm.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); + } + .offcanvas-sm.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); + } + .offcanvas-sm.showing, .offcanvas-sm.show:not(.hiding) { + transform: none; + } + .offcanvas-sm.showing, .offcanvas-sm.hiding, .offcanvas-sm.show { + visibility: visible; + } +} +@media (min-width: 576px) { + .offcanvas-sm { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important; + } + .offcanvas-sm .offcanvas-header { + display: none; + } + .offcanvas-sm .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important; + } +} + +@media (max-width: 767.98px) { + .offcanvas-md { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + box-shadow: var(--bs-offcanvas-box-shadow); + transition: var(--bs-offcanvas-transition); + } +} +@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-md { + transition: none; + } +} +@media (max-width: 767.98px) { + .offcanvas-md.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); + } + .offcanvas-md.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); + } + .offcanvas-md.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); + } + .offcanvas-md.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); + } + .offcanvas-md.showing, .offcanvas-md.show:not(.hiding) { + transform: none; + } + .offcanvas-md.showing, .offcanvas-md.hiding, .offcanvas-md.show { + visibility: visible; + } +} +@media (min-width: 768px) { + .offcanvas-md { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important; + } + .offcanvas-md .offcanvas-header { + display: none; + } + .offcanvas-md .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important; + } +} + +@media (max-width: 991.98px) { + .offcanvas-lg { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + box-shadow: var(--bs-offcanvas-box-shadow); + transition: var(--bs-offcanvas-transition); + } +} +@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-lg { + transition: none; + } +} +@media (max-width: 991.98px) { + .offcanvas-lg.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); + } + .offcanvas-lg.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); + } + .offcanvas-lg.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); + } + .offcanvas-lg.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); + } + .offcanvas-lg.showing, .offcanvas-lg.show:not(.hiding) { + transform: none; + } + .offcanvas-lg.showing, .offcanvas-lg.hiding, .offcanvas-lg.show { + visibility: visible; + } +} +@media (min-width: 992px) { + .offcanvas-lg { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important; + } + .offcanvas-lg .offcanvas-header { + display: none; + } + .offcanvas-lg .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important; + } +} + +@media (max-width: 1199.98px) { + .offcanvas-xl { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + box-shadow: var(--bs-offcanvas-box-shadow); + transition: var(--bs-offcanvas-transition); + } +} +@media (max-width: 1199.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-xl { + transition: none; + } +} +@media (max-width: 1199.98px) { + .offcanvas-xl.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); + } + .offcanvas-xl.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); + } + .offcanvas-xl.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); + } + .offcanvas-xl.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); + } + .offcanvas-xl.showing, .offcanvas-xl.show:not(.hiding) { + transform: none; + } + .offcanvas-xl.showing, .offcanvas-xl.hiding, .offcanvas-xl.show { + visibility: visible; + } +} +@media (min-width: 1200px) { + .offcanvas-xl { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important; + } + .offcanvas-xl .offcanvas-header { + display: none; + } + .offcanvas-xl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important; + } +} + +@media (max-width: 1399.98px) { + .offcanvas-xxl { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + box-shadow: var(--bs-offcanvas-box-shadow); + transition: var(--bs-offcanvas-transition); + } +} +@media (max-width: 1399.98px) and (prefers-reduced-motion: reduce) { + .offcanvas-xxl { + transition: none; + } +} +@media (max-width: 1399.98px) { + .offcanvas-xxl.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); + } + .offcanvas-xxl.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); + } + .offcanvas-xxl.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); + } + .offcanvas-xxl.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); + } + .offcanvas-xxl.showing, .offcanvas-xxl.show:not(.hiding) { + transform: none; + } + .offcanvas-xxl.showing, .offcanvas-xxl.hiding, .offcanvas-xxl.show { + visibility: visible; + } +} +@media (min-width: 1400px) { + .offcanvas-xxl { + --bs-offcanvas-height: auto; + --bs-offcanvas-border-width: 0; + background-color: transparent !important; + } + .offcanvas-xxl .offcanvas-header { + display: none; + } + .offcanvas-xxl .offcanvas-body { + display: flex; + flex-grow: 0; + padding: 0; + overflow-y: visible; + background-color: transparent !important; + } +} + +.offcanvas { + position: fixed; + bottom: 0; + z-index: var(--bs-offcanvas-zindex); + display: flex; + flex-direction: column; + max-width: 100%; + color: var(--bs-offcanvas-color); + visibility: hidden; + background-color: var(--bs-offcanvas-bg); + background-clip: padding-box; + outline: 0; + box-shadow: var(--bs-offcanvas-box-shadow); + transition: var(--bs-offcanvas-transition); +} +@media (prefers-reduced-motion: reduce) { + .offcanvas { + transition: none; + } +} +.offcanvas.offcanvas-start { + top: 0; + left: 0; + width: var(--bs-offcanvas-width); + border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(-100%); +} +.offcanvas.offcanvas-end { + top: 0; + right: 0; + width: var(--bs-offcanvas-width); + border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateX(100%); +} +.offcanvas.offcanvas-top { + top: 0; + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(-100%); +} +.offcanvas.offcanvas-bottom { + right: 0; + left: 0; + height: var(--bs-offcanvas-height); + max-height: 100%; + border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color); + transform: translateY(100%); +} +.offcanvas.showing, .offcanvas.show:not(.hiding) { + transform: none; +} +.offcanvas.showing, .offcanvas.hiding, .offcanvas.show { + visibility: visible; +} + +.offcanvas-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000; +} +.offcanvas-backdrop.fade { + opacity: 0; +} +.offcanvas-backdrop.show { + opacity: 0.5; +} + +.offcanvas-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x); +} +.offcanvas-header .btn-close { + padding: calc(var(--bs-offcanvas-padding-y) * 0.5) calc(var(--bs-offcanvas-padding-x) * 0.5); + margin-top: calc(-0.5 * var(--bs-offcanvas-padding-y)); + margin-right: calc(-0.5 * var(--bs-offcanvas-padding-x)); + margin-bottom: calc(-0.5 * var(--bs-offcanvas-padding-y)); +} + +.offcanvas-title { + margin-bottom: 0; + line-height: var(--bs-offcanvas-title-line-height); +} + +.offcanvas-body { + flex-grow: 1; + padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x); + overflow-y: auto; +} + +.placeholder { + display: inline-block; + min-height: 1em; + vertical-align: middle; + cursor: wait; + background-color: currentcolor; + opacity: 0.5; +} +.placeholder.btn::before { + display: inline-block; + content: ""; +} + +.placeholder-xs { + min-height: 0.6em; +} + +.placeholder-sm { + min-height: 0.8em; +} + +.placeholder-lg { + min-height: 1.2em; +} + +.placeholder-glow .placeholder { + animation: placeholder-glow 2s ease-in-out infinite; +} + +@keyframes placeholder-glow { + 50% { + opacity: 0.2; + } +} +.placeholder-wave { + -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); + mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%); + -webkit-mask-size: 200% 100%; + mask-size: 200% 100%; + animation: placeholder-wave 2s linear infinite; +} + +@keyframes placeholder-wave { + 100% { + -webkit-mask-position: -200% 0%; + mask-position: -200% 0%; + } +} +.clearfix::after { + display: block; + clear: both; + content: ""; +} + +.text-bg-primary { + color: #fff !important; + background-color: RGBA(var(--bs-primary-rgb), var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-secondary { + color: #000 !important; + background-color: RGBA(var(--bs-secondary-rgb), var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-success { + color: #fff !important; + background-color: RGBA(var(--bs-success-rgb), var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-info { + color: #fff !important; + background-color: RGBA(var(--bs-info-rgb), var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-warning { + color: #fff !important; + background-color: RGBA(var(--bs-warning-rgb), var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-danger { + color: #fff !important; + background-color: RGBA(var(--bs-danger-rgb), var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-light { + color: #000 !important; + background-color: RGBA(var(--bs-light-rgb), var(--bs-bg-opacity, 1)) !important; +} + +.text-bg-dark { + color: #fff !important; + background-color: RGBA(var(--bs-dark-rgb), var(--bs-bg-opacity, 1)) !important; +} + +.link-primary { + color: RGBA(var(--bs-primary-rgb), var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(var(--bs-primary-rgb), var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(var(--bs-primary-rgb), var(--bs-link-underline-opacity, 1)) !important; +} +.link-primary:hover, .link-primary:focus { + color: RGBA(42, 71, 184, var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(42, 71, 184, var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(42, 71, 184, var(--bs-link-underline-opacity, 1)) !important; +} + +.link-secondary { + color: RGBA(var(--bs-secondary-rgb), var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(var(--bs-secondary-rgb), var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(var(--bs-secondary-rgb), var(--bs-link-underline-opacity, 1)) !important; +} +.link-secondary:hover, .link-secondary:focus { + color: RGBA(255, 255, 255, var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(255, 255, 255, var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(255, 255, 255, var(--bs-link-underline-opacity, 1)) !important; +} + +.link-success { + color: RGBA(var(--bs-success-rgb), var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(var(--bs-success-rgb), var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(var(--bs-success-rgb), var(--bs-link-underline-opacity, 1)) !important; +} +.link-success:hover, .link-success:focus { + color: RGBA(38, 143, 102, var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(38, 143, 102, var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(38, 143, 102, var(--bs-link-underline-opacity, 1)) !important; +} + +.link-info { + color: RGBA(var(--bs-info-rgb), var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(var(--bs-info-rgb), var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(var(--bs-info-rgb), var(--bs-link-underline-opacity, 1)) !important; +} +.link-info:hover, .link-info:focus { + color: RGBA(32, 98, 145, var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(32, 98, 145, var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(32, 98, 145, var(--bs-link-underline-opacity, 1)) !important; +} + +.link-warning { + color: RGBA(var(--bs-warning-rgb), var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(var(--bs-warning-rgb), var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(var(--bs-warning-rgb), var(--bs-link-underline-opacity, 1)) !important; +} +.link-warning:hover, .link-warning:focus { + color: RGBA(195, 151, 78, var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(195, 151, 78, var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(195, 151, 78, var(--bs-link-underline-opacity, 1)) !important; +} + +.link-danger { + color: RGBA(var(--bs-danger-rgb), var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(var(--bs-danger-rgb), var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(var(--bs-danger-rgb), var(--bs-link-underline-opacity, 1)) !important; +} +.link-danger:hover, .link-danger:focus { + color: RGBA(174, 33, 37, var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(174, 33, 37, var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(174, 33, 37, var(--bs-link-underline-opacity, 1)) !important; +} + +.link-light { + color: RGBA(var(--bs-light-rgb), var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(var(--bs-light-rgb), var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(var(--bs-light-rgb), var(--bs-link-underline-opacity, 1)) !important; +} +.link-light:hover, .link-light:focus { + color: RGBA(249, 250, 251, var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(249, 250, 251, var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(249, 250, 251, var(--bs-link-underline-opacity, 1)) !important; +} + +.link-dark { + color: RGBA(var(--bs-dark-rgb), var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(var(--bs-dark-rgb), var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(var(--bs-dark-rgb), var(--bs-link-underline-opacity, 1)) !important; +} +.link-dark:hover, .link-dark:focus { + color: RGBA(26, 30, 33, var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(26, 30, 33, var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(26, 30, 33, var(--bs-link-underline-opacity, 1)) !important; +} + +.link-body-emphasis { + color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 1)) !important; + -webkit-text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 1)) !important; +} +.link-body-emphasis:hover, .link-body-emphasis:focus { + color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 0.75)) !important; + -webkit-text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 0.75)) !important; + text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 0.75)) !important; +} + +.focus-ring:focus { + outline: 0; + box-shadow: var(--bs-focus-ring-x, 0) var(--bs-focus-ring-y, 0) var(--bs-focus-ring-blur, 0) var(--bs-focus-ring-width) var(--bs-focus-ring-color); +} + +.icon-link { + display: inline-flex; + gap: 0.375rem; + align-items: center; + -webkit-text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 0.5)); + text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 0.5)); + text-underline-offset: 0.25em; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} +.icon-link > .bi { + flex-shrink: 0; + width: 1em; + height: 1em; + fill: currentcolor; + transition: 0.2s ease-in-out transform; +} +@media (prefers-reduced-motion: reduce) { + .icon-link > .bi { + transition: none; + } +} + +.icon-link-hover:hover > .bi, .icon-link-hover:focus-visible > .bi { + transform: var(--bs-icon-link-transform, translate3d(0.25em, 0, 0)); +} + +.ratio { + position: relative; + width: 100%; +} +.ratio::before { + display: block; + padding-top: var(--bs-aspect-ratio); + content: ""; +} +.ratio > * { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.ratio-1x1 { + --bs-aspect-ratio: 100%; +} + +.ratio-4x3 { + --bs-aspect-ratio: 75%; +} + +.ratio-16x9 { + --bs-aspect-ratio: 56.25%; +} + +.ratio-21x9 { + --bs-aspect-ratio: 42.8571428571%; +} + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; +} + +.sticky-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; +} + +.sticky-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020; +} + +@media (min-width: 576px) { + .sticky-sm-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } + .sticky-sm-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020; + } +} +@media (min-width: 768px) { + .sticky-md-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } + .sticky-md-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020; + } +} +@media (min-width: 992px) { + .sticky-lg-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } + .sticky-lg-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020; + } +} +@media (min-width: 1200px) { + .sticky-xl-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } + .sticky-xl-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020; + } +} +@media (min-width: 1400px) { + .sticky-xxl-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } + .sticky-xxl-bottom { + position: -webkit-sticky; + position: sticky; + bottom: 0; + z-index: 1020; + } +} +.hstack { + display: flex; + flex-direction: row; + align-items: center; + align-self: stretch; +} + +.vstack { + display: flex; + flex: 1 1 auto; + flex-direction: column; + align-self: stretch; +} + +.visually-hidden, +.visually-hidden-focusable:not(:focus):not(:focus-within) { + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + white-space: nowrap !important; + border: 0 !important; +} +.visually-hidden:not(caption), +.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption) { + position: absolute !important; +} + +.stretched-link::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + content: ""; +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.vr { + display: inline-block; + align-self: stretch; + width: var(--bs-border-width); + min-height: 1em; + background-color: currentcolor; + opacity: 0.25; +} + +.align-baseline { + vertical-align: baseline !important; +} + +.align-top { + vertical-align: top !important; +} + +.align-middle { + vertical-align: middle !important; +} + +.align-bottom { + vertical-align: bottom !important; +} + +.align-text-bottom { + vertical-align: text-bottom !important; +} + +.align-text-top { + vertical-align: text-top !important; +} + +.float-start { + float: left !important; +} + +.float-end { + float: right !important; +} + +.float-none { + float: none !important; +} + +.object-fit-contain { + -o-object-fit: contain !important; + object-fit: contain !important; +} + +.object-fit-cover { + -o-object-fit: cover !important; + object-fit: cover !important; +} + +.object-fit-fill { + -o-object-fit: fill !important; + object-fit: fill !important; +} + +.object-fit-scale { + -o-object-fit: scale-down !important; + object-fit: scale-down !important; +} + +.object-fit-none { + -o-object-fit: none !important; + object-fit: none !important; +} + +.opacity-0 { + opacity: 0 !important; +} + +.opacity-25 { + opacity: 0.25 !important; +} + +.opacity-50 { + opacity: 0.5 !important; +} + +.opacity-75 { + opacity: 0.75 !important; +} + +.opacity-100 { + opacity: 1 !important; +} + +.overflow-auto { + overflow: auto !important; +} + +.overflow-hidden { + overflow: hidden !important; +} + +.overflow-visible { + overflow: visible !important; +} + +.overflow-scroll { + overflow: scroll !important; +} + +.overflow-x-auto { + overflow-x: auto !important; +} + +.overflow-x-hidden { + overflow-x: hidden !important; +} + +.overflow-x-visible { + overflow-x: visible !important; +} + +.overflow-x-scroll { + overflow-x: scroll !important; +} + +.overflow-y-auto { + overflow-y: auto !important; +} + +.overflow-y-hidden { + overflow-y: hidden !important; +} + +.overflow-y-visible { + overflow-y: visible !important; +} + +.overflow-y-scroll { + overflow-y: scroll !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-grid { + display: grid !important; +} + +.d-inline-grid { + display: inline-grid !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: flex !important; +} + +.d-inline-flex { + display: inline-flex !important; +} + +.d-none { + display: none !important; +} + +.shadow { + box-shadow: var(--bs-box-shadow) !important; +} + +.shadow-sm { + box-shadow: var(--bs-box-shadow-sm) !important; +} + +.shadow-lg { + box-shadow: var(--bs-box-shadow-lg) !important; +} + +.shadow-none { + box-shadow: none !important; +} + +.focus-ring-primary { + --bs-focus-ring-color: rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity)); +} + +.focus-ring-secondary { + --bs-focus-ring-color: rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity)); +} + +.focus-ring-success { + --bs-focus-ring-color: rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity)); +} + +.focus-ring-info { + --bs-focus-ring-color: rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity)); +} + +.focus-ring-warning { + --bs-focus-ring-color: rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity)); +} + +.focus-ring-danger { + --bs-focus-ring-color: rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity)); +} + +.focus-ring-light { + --bs-focus-ring-color: rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity)); +} + +.focus-ring-dark { + --bs-focus-ring-color: rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity)); +} + +.position-static { + position: static !important; +} + +.position-relative { + position: relative !important; +} + +.position-absolute { + position: absolute !important; +} + +.position-fixed { + position: fixed !important; +} + +.position-sticky { + position: -webkit-sticky !important; + position: sticky !important; +} + +.top-0 { + top: 0 !important; +} + +.top-50 { + top: 50% !important; +} + +.top-100 { + top: 100% !important; +} + +.bottom-0 { + bottom: 0 !important; +} + +.bottom-50 { + bottom: 50% !important; +} + +.bottom-100 { + bottom: 100% !important; +} + +.start-0 { + left: 0 !important; +} + +.start-50 { + left: 50% !important; +} + +.start-100 { + left: 100% !important; +} + +.end-0 { + right: 0 !important; +} + +.end-50 { + right: 50% !important; +} + +.end-100 { + right: 100% !important; +} + +.translate-middle { + transform: translate(-50%, -50%) !important; +} + +.translate-middle-x { + transform: translateX(-50%) !important; +} + +.translate-middle-y { + transform: translateY(-50%) !important; +} + +.border { + border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; +} + +.border-0 { + border: 0 !important; +} + +.border-top { + border-top: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; +} + +.border-top-0 { + border-top: 0 !important; +} + +.border-end { + border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; +} + +.border-end-0 { + border-right: 0 !important; +} + +.border-bottom { + border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; +} + +.border-bottom-0 { + border-bottom: 0 !important; +} + +.border-start { + border-left: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important; +} + +.border-start-0 { + border-left: 0 !important; +} + +.border-primary { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important; +} + +.border-secondary { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important; +} + +.border-success { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important; +} + +.border-info { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important; +} + +.border-warning { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important; +} + +.border-danger { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important; +} + +.border-light { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important; +} + +.border-dark { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important; +} + +.border-black { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-black-rgb), var(--bs-border-opacity)) !important; +} + +.border-white { + --bs-border-opacity: 1; + border-color: rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important; +} + +.border-primary-subtle { + border-color: var(--bs-primary-border-subtle) !important; +} + +.border-secondary-subtle { + border-color: var(--bs-secondary-border-subtle) !important; +} + +.border-success-subtle { + border-color: var(--bs-success-border-subtle) !important; +} + +.border-info-subtle { + border-color: var(--bs-info-border-subtle) !important; +} + +.border-warning-subtle { + border-color: var(--bs-warning-border-subtle) !important; +} + +.border-danger-subtle { + border-color: var(--bs-danger-border-subtle) !important; +} + +.border-light-subtle { + border-color: var(--bs-light-border-subtle) !important; +} + +.border-dark-subtle { + border-color: var(--bs-dark-border-subtle) !important; +} + +.border-1 { + border-width: 1px !important; +} + +.border-2 { + border-width: 2px !important; +} + +.border-3 { + border-width: 3px !important; +} + +.border-4 { + border-width: 4px !important; +} + +.border-5 { + border-width: 5px !important; +} + +.border-opacity-10 { + --bs-border-opacity: 0.1; +} + +.border-opacity-25 { + --bs-border-opacity: 0.25; +} + +.border-opacity-50 { + --bs-border-opacity: 0.5; +} + +.border-opacity-75 { + --bs-border-opacity: 0.75; +} + +.border-opacity-100 { + --bs-border-opacity: 1; +} + +.w-25 { + width: 25% !important; +} + +.w-50 { + width: 50% !important; +} + +.w-75 { + width: 75% !important; +} + +.w-100 { + width: 100% !important; +} + +.w-auto { + width: auto !important; +} + +.mw-100 { + max-width: 100% !important; +} + +.vw-100 { + width: 100vw !important; +} + +.min-vw-100 { + min-width: 100vw !important; +} + +.h-25 { + height: 25% !important; +} + +.h-50 { + height: 50% !important; +} + +.h-75 { + height: 75% !important; +} + +.h-100 { + height: 100% !important; +} + +.h-auto { + height: auto !important; +} + +.mh-100 { + max-height: 100% !important; +} + +.vh-100 { + height: 100vh !important; +} + +.min-vh-100 { + min-height: 100vh !important; +} + +.flex-fill { + flex: 1 1 auto !important; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-row-reverse { + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + flex-direction: column-reverse !important; +} + +.flex-grow-0 { + flex-grow: 0 !important; +} + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.flex-shrink-0 { + flex-shrink: 0 !important; +} + +.flex-shrink-1 { + flex-shrink: 1 !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + justify-content: flex-start !important; +} + +.justify-content-end { + justify-content: flex-end !important; +} + +.justify-content-center { + justify-content: center !important; +} + +.justify-content-between { + justify-content: space-between !important; +} + +.justify-content-around { + justify-content: space-around !important; +} + +.justify-content-evenly { + justify-content: space-evenly !important; +} + +.align-items-start { + align-items: flex-start !important; +} + +.align-items-end { + align-items: flex-end !important; +} + +.align-items-center { + align-items: center !important; +} + +.align-items-baseline { + align-items: baseline !important; +} + +.align-items-stretch { + align-items: stretch !important; +} + +.align-content-start { + align-content: flex-start !important; +} + +.align-content-end { + align-content: flex-end !important; +} + +.align-content-center { + align-content: center !important; +} + +.align-content-between { + align-content: space-between !important; +} + +.align-content-around { + align-content: space-around !important; +} + +.align-content-stretch { + align-content: stretch !important; +} + +.align-self-auto { + align-self: auto !important; +} + +.align-self-start { + align-self: flex-start !important; +} + +.align-self-end { + align-self: flex-end !important; +} + +.align-self-center { + align-self: center !important; +} + +.align-self-baseline { + align-self: baseline !important; +} + +.align-self-stretch { + align-self: stretch !important; +} + +.order-first { + order: -1 !important; +} + +.order-0 { + order: 0 !important; +} + +.order-1 { + order: 1 !important; +} + +.order-2 { + order: 2 !important; +} + +.order-3 { + order: 3 !important; +} + +.order-4 { + order: 4 !important; +} + +.order-5 { + order: 5 !important; +} + +.order-last { + order: 6 !important; +} + +.m-0 { + margin: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important; +} + +.mx-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; +} + +.mx-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; +} + +.mx-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; +} + +.mx-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; +} + +.mx-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; +} + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important; +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.my-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; +} + +.my-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important; +} + +.mt-0 { + margin-top: 0 !important; +} + +.mt-1 { + margin-top: 0.25rem !important; +} + +.mt-2 { + margin-top: 0.5rem !important; +} + +.mt-3 { + margin-top: 1rem !important; +} + +.mt-4 { + margin-top: 1.5rem !important; +} + +.mt-5 { + margin-top: 3rem !important; +} + +.mt-auto { + margin-top: auto !important; +} + +.me-0 { + margin-right: 0 !important; +} + +.me-1 { + margin-right: 0.25rem !important; +} + +.me-2 { + margin-right: 0.5rem !important; +} + +.me-3 { + margin-right: 1rem !important; +} + +.me-4 { + margin-right: 1.5rem !important; +} + +.me-5 { + margin-right: 3rem !important; +} + +.me-auto { + margin-right: auto !important; +} + +.mb-0 { + margin-bottom: 0 !important; +} + +.mb-1 { + margin-bottom: 0.25rem !important; +} + +.mb-2 { + margin-bottom: 0.5rem !important; +} + +.mb-3 { + margin-bottom: 1rem !important; +} + +.mb-4 { + margin-bottom: 1.5rem !important; +} + +.mb-5 { + margin-bottom: 3rem !important; +} + +.mb-auto { + margin-bottom: auto !important; +} + +.ms-0 { + margin-left: 0 !important; +} + +.ms-1 { + margin-left: 0.25rem !important; +} + +.ms-2 { + margin-left: 0.5rem !important; +} + +.ms-3 { + margin-left: 1rem !important; +} + +.ms-4 { + margin-left: 1.5rem !important; +} + +.ms-5 { + margin-left: 3rem !important; +} + +.ms-auto { + margin-left: auto !important; +} + +.p-0 { + padding: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important; +} + +.px-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; +} + +.px-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; +} + +.px-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; +} + +.px-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; +} + +.px-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.py-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; +} + +.py-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; +} + +.pt-0 { + padding-top: 0 !important; +} + +.pt-1 { + padding-top: 0.25rem !important; +} + +.pt-2 { + padding-top: 0.5rem !important; +} + +.pt-3 { + padding-top: 1rem !important; +} + +.pt-4 { + padding-top: 1.5rem !important; +} + +.pt-5 { + padding-top: 3rem !important; +} + +.pe-0 { + padding-right: 0 !important; +} + +.pe-1 { + padding-right: 0.25rem !important; +} + +.pe-2 { + padding-right: 0.5rem !important; +} + +.pe-3 { + padding-right: 1rem !important; +} + +.pe-4 { + padding-right: 1.5rem !important; +} + +.pe-5 { + padding-right: 3rem !important; +} + +.pb-0 { + padding-bottom: 0 !important; +} + +.pb-1 { + padding-bottom: 0.25rem !important; +} + +.pb-2 { + padding-bottom: 0.5rem !important; +} + +.pb-3 { + padding-bottom: 1rem !important; +} + +.pb-4 { + padding-bottom: 1.5rem !important; +} + +.pb-5 { + padding-bottom: 3rem !important; +} + +.ps-0 { + padding-left: 0 !important; +} + +.ps-1 { + padding-left: 0.25rem !important; +} + +.ps-2 { + padding-left: 0.5rem !important; +} + +.ps-3 { + padding-left: 1rem !important; +} + +.ps-4 { + padding-left: 1.5rem !important; +} + +.ps-5 { + padding-left: 3rem !important; +} + +.gap-0 { + gap: 0 !important; +} + +.gap-1 { + gap: 0.25rem !important; +} + +.gap-2 { + gap: 0.5rem !important; +} + +.gap-3 { + gap: 1rem !important; +} + +.gap-4 { + gap: 1.5rem !important; +} + +.gap-5 { + gap: 3rem !important; +} + +.row-gap-0 { + row-gap: 0 !important; +} + +.row-gap-1 { + row-gap: 0.25rem !important; +} + +.row-gap-2 { + row-gap: 0.5rem !important; +} + +.row-gap-3 { + row-gap: 1rem !important; +} + +.row-gap-4 { + row-gap: 1.5rem !important; +} + +.row-gap-5 { + row-gap: 3rem !important; +} + +.column-gap-0 { + -moz-column-gap: 0 !important; + column-gap: 0 !important; +} + +.column-gap-1 { + -moz-column-gap: 0.25rem !important; + column-gap: 0.25rem !important; +} + +.column-gap-2 { + -moz-column-gap: 0.5rem !important; + column-gap: 0.5rem !important; +} + +.column-gap-3 { + -moz-column-gap: 1rem !important; + column-gap: 1rem !important; +} + +.column-gap-4 { + -moz-column-gap: 1.5rem !important; + column-gap: 1.5rem !important; +} + +.column-gap-5 { + -moz-column-gap: 3rem !important; + column-gap: 3rem !important; +} + +.font-monospace { + font-family: var(--bs-font-monospace) !important; +} + +.fs-1 { + font-size: calc(1.375rem + 1.5vw) !important; +} + +.fs-2 { + font-size: calc(1.325rem + 0.9vw) !important; +} + +.fs-3 { + font-size: calc(1.3rem + 0.6vw) !important; +} + +.fs-4 { + font-size: calc(1.275rem + 0.3vw) !important; +} + +.fs-5 { + font-size: 1.25rem !important; +} + +.fs-6 { + font-size: 1rem !important; +} + +.fst-italic { + font-style: italic !important; +} + +.fst-normal { + font-style: normal !important; +} + +.fw-lighter { + font-weight: lighter !important; +} + +.fw-light { + font-weight: 300 !important; +} + +.fw-normal { + font-weight: 400 !important; +} + +.fw-medium { + font-weight: 500 !important; +} + +.fw-semibold { + font-weight: 600 !important; +} + +.fw-bold { + font-weight: 700 !important; +} + +.fw-bolder { + font-weight: bolder !important; +} + +.lh-1 { + line-height: 1 !important; +} + +.lh-sm { + line-height: 1.25 !important; +} + +.lh-base { + line-height: 1.5 !important; +} + +.lh-lg { + line-height: 2 !important; +} + +.text-start { + text-align: left !important; +} + +.text-end { + text-align: right !important; +} + +.text-center { + text-align: center !important; +} + +.text-decoration-none { + text-decoration: none !important; +} + +.text-decoration-underline { + text-decoration: underline !important; +} + +.text-decoration-line-through { + text-decoration: line-through !important; +} + +.text-lowercase { + text-transform: lowercase !important; +} + +.text-uppercase { + text-transform: uppercase !important; +} + +.text-capitalize { + text-transform: capitalize !important; +} + +.text-wrap { + white-space: normal !important; +} + +.text-nowrap { + white-space: nowrap !important; +} + +/* rtl:begin:remove */ +.text-break { + word-wrap: break-word !important; + word-break: break-word !important; +} + +/* rtl:end:remove */ +.text-primary { + --bs-text-opacity: 1; + color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important; +} + +.text-secondary { + --bs-text-opacity: 1; + color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important; +} + +.text-success { + --bs-text-opacity: 1; + color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important; +} + +.text-info { + --bs-text-opacity: 1; + color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important; +} + +.text-warning { + --bs-text-opacity: 1; + color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important; +} + +.text-danger { + --bs-text-opacity: 1; + color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important; +} + +.text-light { + --bs-text-opacity: 1; + color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important; +} + +.text-dark { + --bs-text-opacity: 1; + color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important; +} + +.text-black { + --bs-text-opacity: 1; + color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important; +} + +.text-white { + --bs-text-opacity: 1; + color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important; +} + +.text-body { + --bs-text-opacity: 1; + color: rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important; +} + +.text-muted { + --bs-text-opacity: 1; + color: var(--bs-secondary-color) !important; +} + +.text-black-50 { + --bs-text-opacity: 1; + color: rgba(0, 0, 0, 0.5) !important; +} + +.text-white-50 { + --bs-text-opacity: 1; + color: rgba(255, 255, 255, 0.5) !important; +} + +.text-body-secondary { + --bs-text-opacity: 1; + color: var(--bs-secondary-color) !important; +} + +.text-body-tertiary { + --bs-text-opacity: 1; + color: var(--bs-tertiary-color) !important; +} + +.text-body-emphasis { + --bs-text-opacity: 1; + color: var(--bs-emphasis-color) !important; +} + +.text-reset { + --bs-text-opacity: 1; + color: inherit !important; +} + +.text-opacity-25 { + --bs-text-opacity: 0.25; +} + +.text-opacity-50 { + --bs-text-opacity: 0.5; +} + +.text-opacity-75 { + --bs-text-opacity: 0.75; +} + +.text-opacity-100 { + --bs-text-opacity: 1; +} + +.text-primary-emphasis { + color: var(--bs-primary-text-emphasis) !important; +} + +.text-secondary-emphasis { + color: var(--bs-secondary-text-emphasis) !important; +} + +.text-success-emphasis { + color: var(--bs-success-text-emphasis) !important; +} + +.text-info-emphasis { + color: var(--bs-info-text-emphasis) !important; +} + +.text-warning-emphasis { + color: var(--bs-warning-text-emphasis) !important; +} + +.text-danger-emphasis { + color: var(--bs-danger-text-emphasis) !important; +} + +.text-light-emphasis { + color: var(--bs-light-text-emphasis) !important; +} + +.text-dark-emphasis { + color: var(--bs-dark-text-emphasis) !important; +} + +.link-opacity-10 { + --bs-link-opacity: 0.1; +} + +.link-opacity-10-hover:hover { + --bs-link-opacity: 0.1; +} + +.link-opacity-25 { + --bs-link-opacity: 0.25; +} + +.link-opacity-25-hover:hover { + --bs-link-opacity: 0.25; +} + +.link-opacity-50 { + --bs-link-opacity: 0.5; +} + +.link-opacity-50-hover:hover { + --bs-link-opacity: 0.5; +} + +.link-opacity-75 { + --bs-link-opacity: 0.75; +} + +.link-opacity-75-hover:hover { + --bs-link-opacity: 0.75; +} + +.link-opacity-100 { + --bs-link-opacity: 1; +} + +.link-opacity-100-hover:hover { + --bs-link-opacity: 1; +} + +.link-offset-1 { + text-underline-offset: 0.125em !important; +} + +.link-offset-1-hover:hover { + text-underline-offset: 0.125em !important; +} + +.link-offset-2 { + text-underline-offset: 0.25em !important; +} + +.link-offset-2-hover:hover { + text-underline-offset: 0.25em !important; +} + +.link-offset-3 { + text-underline-offset: 0.375em !important; +} + +.link-offset-3-hover:hover { + text-underline-offset: 0.375em !important; +} + +.link-underline-primary { + --bs-link-underline-opacity: 1; + -webkit-text-decoration-color: rgba(var(--bs-primary-rgb), var(--bs-link-underline-opacity)) !important; + text-decoration-color: rgba(var(--bs-primary-rgb), var(--bs-link-underline-opacity)) !important; +} + +.link-underline-secondary { + --bs-link-underline-opacity: 1; + -webkit-text-decoration-color: rgba(var(--bs-secondary-rgb), var(--bs-link-underline-opacity)) !important; + text-decoration-color: rgba(var(--bs-secondary-rgb), var(--bs-link-underline-opacity)) !important; +} + +.link-underline-success { + --bs-link-underline-opacity: 1; + -webkit-text-decoration-color: rgba(var(--bs-success-rgb), var(--bs-link-underline-opacity)) !important; + text-decoration-color: rgba(var(--bs-success-rgb), var(--bs-link-underline-opacity)) !important; +} + +.link-underline-info { + --bs-link-underline-opacity: 1; + -webkit-text-decoration-color: rgba(var(--bs-info-rgb), var(--bs-link-underline-opacity)) !important; + text-decoration-color: rgba(var(--bs-info-rgb), var(--bs-link-underline-opacity)) !important; +} + +.link-underline-warning { + --bs-link-underline-opacity: 1; + -webkit-text-decoration-color: rgba(var(--bs-warning-rgb), var(--bs-link-underline-opacity)) !important; + text-decoration-color: rgba(var(--bs-warning-rgb), var(--bs-link-underline-opacity)) !important; +} + +.link-underline-danger { + --bs-link-underline-opacity: 1; + -webkit-text-decoration-color: rgba(var(--bs-danger-rgb), var(--bs-link-underline-opacity)) !important; + text-decoration-color: rgba(var(--bs-danger-rgb), var(--bs-link-underline-opacity)) !important; +} + +.link-underline-light { + --bs-link-underline-opacity: 1; + -webkit-text-decoration-color: rgba(var(--bs-light-rgb), var(--bs-link-underline-opacity)) !important; + text-decoration-color: rgba(var(--bs-light-rgb), var(--bs-link-underline-opacity)) !important; +} + +.link-underline-dark { + --bs-link-underline-opacity: 1; + -webkit-text-decoration-color: rgba(var(--bs-dark-rgb), var(--bs-link-underline-opacity)) !important; + text-decoration-color: rgba(var(--bs-dark-rgb), var(--bs-link-underline-opacity)) !important; +} + +.link-underline { + --bs-link-underline-opacity: 1; + -webkit-text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-underline-opacity, 1)) !important; + text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-underline-opacity, 1)) !important; +} + +.link-underline-opacity-0 { + --bs-link-underline-opacity: 0; +} + +.link-underline-opacity-0-hover:hover { + --bs-link-underline-opacity: 0; +} + +.link-underline-opacity-10 { + --bs-link-underline-opacity: 0.1; +} + +.link-underline-opacity-10-hover:hover { + --bs-link-underline-opacity: 0.1; +} + +.link-underline-opacity-25 { + --bs-link-underline-opacity: 0.25; +} + +.link-underline-opacity-25-hover:hover { + --bs-link-underline-opacity: 0.25; +} + +.link-underline-opacity-50 { + --bs-link-underline-opacity: 0.5; +} + +.link-underline-opacity-50-hover:hover { + --bs-link-underline-opacity: 0.5; +} + +.link-underline-opacity-75 { + --bs-link-underline-opacity: 0.75; +} + +.link-underline-opacity-75-hover:hover { + --bs-link-underline-opacity: 0.75; +} + +.link-underline-opacity-100 { + --bs-link-underline-opacity: 1; +} + +.link-underline-opacity-100-hover:hover { + --bs-link-underline-opacity: 1; +} + +.bg-primary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-secondary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-success { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-info { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-warning { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-danger { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-light { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-dark { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-black { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-white { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-body { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-transparent { + --bs-bg-opacity: 1; + background-color: transparent !important; +} + +.bg-body-secondary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-secondary-bg-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-body-tertiary { + --bs-bg-opacity: 1; + background-color: rgba(var(--bs-tertiary-bg-rgb), var(--bs-bg-opacity)) !important; +} + +.bg-opacity-10 { + --bs-bg-opacity: 0.1; +} + +.bg-opacity-25 { + --bs-bg-opacity: 0.25; +} + +.bg-opacity-50 { + --bs-bg-opacity: 0.5; +} + +.bg-opacity-75 { + --bs-bg-opacity: 0.75; +} + +.bg-opacity-100 { + --bs-bg-opacity: 1; +} + +.bg-primary-subtle { + background-color: var(--bs-primary-bg-subtle) !important; +} + +.bg-secondary-subtle { + background-color: var(--bs-secondary-bg-subtle) !important; +} + +.bg-success-subtle { + background-color: var(--bs-success-bg-subtle) !important; +} + +.bg-info-subtle { + background-color: var(--bs-info-bg-subtle) !important; +} + +.bg-warning-subtle { + background-color: var(--bs-warning-bg-subtle) !important; +} + +.bg-danger-subtle { + background-color: var(--bs-danger-bg-subtle) !important; +} + +.bg-light-subtle { + background-color: var(--bs-light-bg-subtle) !important; +} + +.bg-dark-subtle { + background-color: var(--bs-dark-bg-subtle) !important; +} + +.bg-gradient { + background-image: var(--bs-gradient) !important; +} + +.user-select-all { + -webkit-user-select: all !important; + -moz-user-select: all !important; + user-select: all !important; +} + +.user-select-auto { + -webkit-user-select: auto !important; + -moz-user-select: auto !important; + user-select: auto !important; +} + +.user-select-none { + -webkit-user-select: none !important; + -moz-user-select: none !important; + user-select: none !important; +} + +.pe-none { + pointer-events: none !important; +} + +.pe-auto { + pointer-events: auto !important; +} + +.rounded { + border-radius: var(--bs-border-radius) !important; +} + +.rounded-0 { + border-radius: 0 !important; +} + +.rounded-1 { + border-radius: var(--bs-border-radius-sm) !important; +} + +.rounded-2 { + border-radius: var(--bs-border-radius) !important; +} + +.rounded-3 { + border-radius: var(--bs-border-radius-lg) !important; +} + +.rounded-4 { + border-radius: var(--bs-border-radius-xl) !important; +} + +.rounded-5 { + border-radius: var(--bs-border-radius-xxl) !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-pill { + border-radius: var(--bs-border-radius-pill) !important; +} + +.rounded-top { + border-top-left-radius: var(--bs-border-radius) !important; + border-top-right-radius: var(--bs-border-radius) !important; +} + +.rounded-top-0 { + border-top-left-radius: 0 !important; + border-top-right-radius: 0 !important; +} + +.rounded-top-1 { + border-top-left-radius: var(--bs-border-radius-sm) !important; + border-top-right-radius: var(--bs-border-radius-sm) !important; +} + +.rounded-top-2 { + border-top-left-radius: var(--bs-border-radius) !important; + border-top-right-radius: var(--bs-border-radius) !important; +} + +.rounded-top-3 { + border-top-left-radius: var(--bs-border-radius-lg) !important; + border-top-right-radius: var(--bs-border-radius-lg) !important; +} + +.rounded-top-4 { + border-top-left-radius: var(--bs-border-radius-xl) !important; + border-top-right-radius: var(--bs-border-radius-xl) !important; +} + +.rounded-top-5 { + border-top-left-radius: var(--bs-border-radius-xxl) !important; + border-top-right-radius: var(--bs-border-radius-xxl) !important; +} + +.rounded-top-circle { + border-top-left-radius: 50% !important; + border-top-right-radius: 50% !important; +} + +.rounded-top-pill { + border-top-left-radius: var(--bs-border-radius-pill) !important; + border-top-right-radius: var(--bs-border-radius-pill) !important; +} + +.rounded-end { + border-top-right-radius: var(--bs-border-radius) !important; + border-bottom-right-radius: var(--bs-border-radius) !important; +} + +.rounded-end-0 { + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; +} + +.rounded-end-1 { + border-top-right-radius: var(--bs-border-radius-sm) !important; + border-bottom-right-radius: var(--bs-border-radius-sm) !important; +} + +.rounded-end-2 { + border-top-right-radius: var(--bs-border-radius) !important; + border-bottom-right-radius: var(--bs-border-radius) !important; +} + +.rounded-end-3 { + border-top-right-radius: var(--bs-border-radius-lg) !important; + border-bottom-right-radius: var(--bs-border-radius-lg) !important; +} + +.rounded-end-4 { + border-top-right-radius: var(--bs-border-radius-xl) !important; + border-bottom-right-radius: var(--bs-border-radius-xl) !important; +} + +.rounded-end-5 { + border-top-right-radius: var(--bs-border-radius-xxl) !important; + border-bottom-right-radius: var(--bs-border-radius-xxl) !important; +} + +.rounded-end-circle { + border-top-right-radius: 50% !important; + border-bottom-right-radius: 50% !important; +} + +.rounded-end-pill { + border-top-right-radius: var(--bs-border-radius-pill) !important; + border-bottom-right-radius: var(--bs-border-radius-pill) !important; +} + +.rounded-bottom { + border-bottom-right-radius: var(--bs-border-radius) !important; + border-bottom-left-radius: var(--bs-border-radius) !important; +} + +.rounded-bottom-0 { + border-bottom-right-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} + +.rounded-bottom-1 { + border-bottom-right-radius: var(--bs-border-radius-sm) !important; + border-bottom-left-radius: var(--bs-border-radius-sm) !important; +} + +.rounded-bottom-2 { + border-bottom-right-radius: var(--bs-border-radius) !important; + border-bottom-left-radius: var(--bs-border-radius) !important; +} + +.rounded-bottom-3 { + border-bottom-right-radius: var(--bs-border-radius-lg) !important; + border-bottom-left-radius: var(--bs-border-radius-lg) !important; +} + +.rounded-bottom-4 { + border-bottom-right-radius: var(--bs-border-radius-xl) !important; + border-bottom-left-radius: var(--bs-border-radius-xl) !important; +} + +.rounded-bottom-5 { + border-bottom-right-radius: var(--bs-border-radius-xxl) !important; + border-bottom-left-radius: var(--bs-border-radius-xxl) !important; +} + +.rounded-bottom-circle { + border-bottom-right-radius: 50% !important; + border-bottom-left-radius: 50% !important; +} + +.rounded-bottom-pill { + border-bottom-right-radius: var(--bs-border-radius-pill) !important; + border-bottom-left-radius: var(--bs-border-radius-pill) !important; +} + +.rounded-start { + border-bottom-left-radius: var(--bs-border-radius) !important; + border-top-left-radius: var(--bs-border-radius) !important; +} + +.rounded-start-0 { + border-bottom-left-radius: 0 !important; + border-top-left-radius: 0 !important; +} + +.rounded-start-1 { + border-bottom-left-radius: var(--bs-border-radius-sm) !important; + border-top-left-radius: var(--bs-border-radius-sm) !important; +} + +.rounded-start-2 { + border-bottom-left-radius: var(--bs-border-radius) !important; + border-top-left-radius: var(--bs-border-radius) !important; +} + +.rounded-start-3 { + border-bottom-left-radius: var(--bs-border-radius-lg) !important; + border-top-left-radius: var(--bs-border-radius-lg) !important; +} + +.rounded-start-4 { + border-bottom-left-radius: var(--bs-border-radius-xl) !important; + border-top-left-radius: var(--bs-border-radius-xl) !important; +} + +.rounded-start-5 { + border-bottom-left-radius: var(--bs-border-radius-xxl) !important; + border-top-left-radius: var(--bs-border-radius-xxl) !important; +} + +.rounded-start-circle { + border-bottom-left-radius: 50% !important; + border-top-left-radius: 50% !important; +} + +.rounded-start-pill { + border-bottom-left-radius: var(--bs-border-radius-pill) !important; + border-top-left-radius: var(--bs-border-radius-pill) !important; +} + +.visible { + visibility: visible !important; +} + +.invisible { + visibility: hidden !important; +} + +.z-n1 { + z-index: -1 !important; +} + +.z-0 { + z-index: 0 !important; +} + +.z-1 { + z-index: 1 !important; +} + +.z-2 { + z-index: 2 !important; +} + +.z-3 { + z-index: 3 !important; +} + +@media (min-width: 576px) { + .float-sm-start { + float: left !important; + } + .float-sm-end { + float: right !important; + } + .float-sm-none { + float: none !important; + } + .object-fit-sm-contain { + -o-object-fit: contain !important; + object-fit: contain !important; + } + .object-fit-sm-cover { + -o-object-fit: cover !important; + object-fit: cover !important; + } + .object-fit-sm-fill { + -o-object-fit: fill !important; + object-fit: fill !important; + } + .object-fit-sm-scale { + -o-object-fit: scale-down !important; + object-fit: scale-down !important; + } + .object-fit-sm-none { + -o-object-fit: none !important; + object-fit: none !important; + } + .d-sm-inline { + display: inline !important; + } + .d-sm-inline-block { + display: inline-block !important; + } + .d-sm-block { + display: block !important; + } + .d-sm-grid { + display: grid !important; + } + .d-sm-inline-grid { + display: inline-grid !important; + } + .d-sm-table { + display: table !important; + } + .d-sm-table-row { + display: table-row !important; + } + .d-sm-table-cell { + display: table-cell !important; + } + .d-sm-flex { + display: flex !important; + } + .d-sm-inline-flex { + display: inline-flex !important; + } + .d-sm-none { + display: none !important; + } + .flex-sm-fill { + flex: 1 1 auto !important; + } + .flex-sm-row { + flex-direction: row !important; + } + .flex-sm-column { + flex-direction: column !important; + } + .flex-sm-row-reverse { + flex-direction: row-reverse !important; + } + .flex-sm-column-reverse { + flex-direction: column-reverse !important; + } + .flex-sm-grow-0 { + flex-grow: 0 !important; + } + .flex-sm-grow-1 { + flex-grow: 1 !important; + } + .flex-sm-shrink-0 { + flex-shrink: 0 !important; + } + .flex-sm-shrink-1 { + flex-shrink: 1 !important; + } + .flex-sm-wrap { + flex-wrap: wrap !important; + } + .flex-sm-nowrap { + flex-wrap: nowrap !important; + } + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-sm-start { + justify-content: flex-start !important; + } + .justify-content-sm-end { + justify-content: flex-end !important; + } + .justify-content-sm-center { + justify-content: center !important; + } + .justify-content-sm-between { + justify-content: space-between !important; + } + .justify-content-sm-around { + justify-content: space-around !important; + } + .justify-content-sm-evenly { + justify-content: space-evenly !important; + } + .align-items-sm-start { + align-items: flex-start !important; + } + .align-items-sm-end { + align-items: flex-end !important; + } + .align-items-sm-center { + align-items: center !important; + } + .align-items-sm-baseline { + align-items: baseline !important; + } + .align-items-sm-stretch { + align-items: stretch !important; + } + .align-content-sm-start { + align-content: flex-start !important; + } + .align-content-sm-end { + align-content: flex-end !important; + } + .align-content-sm-center { + align-content: center !important; + } + .align-content-sm-between { + align-content: space-between !important; + } + .align-content-sm-around { + align-content: space-around !important; + } + .align-content-sm-stretch { + align-content: stretch !important; + } + .align-self-sm-auto { + align-self: auto !important; + } + .align-self-sm-start { + align-self: flex-start !important; + } + .align-self-sm-end { + align-self: flex-end !important; + } + .align-self-sm-center { + align-self: center !important; + } + .align-self-sm-baseline { + align-self: baseline !important; + } + .align-self-sm-stretch { + align-self: stretch !important; + } + .order-sm-first { + order: -1 !important; + } + .order-sm-0 { + order: 0 !important; + } + .order-sm-1 { + order: 1 !important; + } + .order-sm-2 { + order: 2 !important; + } + .order-sm-3 { + order: 3 !important; + } + .order-sm-4 { + order: 4 !important; + } + .order-sm-5 { + order: 5 !important; + } + .order-sm-last { + order: 6 !important; + } + .m-sm-0 { + margin: 0 !important; + } + .m-sm-1 { + margin: 0.25rem !important; + } + .m-sm-2 { + margin: 0.5rem !important; + } + .m-sm-3 { + margin: 1rem !important; + } + .m-sm-4 { + margin: 1.5rem !important; + } + .m-sm-5 { + margin: 3rem !important; + } + .m-sm-auto { + margin: auto !important; + } + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-sm-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-sm-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-sm-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-sm-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-sm-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-sm-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-sm-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-sm-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-sm-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-sm-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-sm-0 { + margin-top: 0 !important; + } + .mt-sm-1 { + margin-top: 0.25rem !important; + } + .mt-sm-2 { + margin-top: 0.5rem !important; + } + .mt-sm-3 { + margin-top: 1rem !important; + } + .mt-sm-4 { + margin-top: 1.5rem !important; + } + .mt-sm-5 { + margin-top: 3rem !important; + } + .mt-sm-auto { + margin-top: auto !important; + } + .me-sm-0 { + margin-right: 0 !important; + } + .me-sm-1 { + margin-right: 0.25rem !important; + } + .me-sm-2 { + margin-right: 0.5rem !important; + } + .me-sm-3 { + margin-right: 1rem !important; + } + .me-sm-4 { + margin-right: 1.5rem !important; + } + .me-sm-5 { + margin-right: 3rem !important; + } + .me-sm-auto { + margin-right: auto !important; + } + .mb-sm-0 { + margin-bottom: 0 !important; + } + .mb-sm-1 { + margin-bottom: 0.25rem !important; + } + .mb-sm-2 { + margin-bottom: 0.5rem !important; + } + .mb-sm-3 { + margin-bottom: 1rem !important; + } + .mb-sm-4 { + margin-bottom: 1.5rem !important; + } + .mb-sm-5 { + margin-bottom: 3rem !important; + } + .mb-sm-auto { + margin-bottom: auto !important; + } + .ms-sm-0 { + margin-left: 0 !important; + } + .ms-sm-1 { + margin-left: 0.25rem !important; + } + .ms-sm-2 { + margin-left: 0.5rem !important; + } + .ms-sm-3 { + margin-left: 1rem !important; + } + .ms-sm-4 { + margin-left: 1.5rem !important; + } + .ms-sm-5 { + margin-left: 3rem !important; + } + .ms-sm-auto { + margin-left: auto !important; + } + .p-sm-0 { + padding: 0 !important; + } + .p-sm-1 { + padding: 0.25rem !important; + } + .p-sm-2 { + padding: 0.5rem !important; + } + .p-sm-3 { + padding: 1rem !important; + } + .p-sm-4 { + padding: 1.5rem !important; + } + .p-sm-5 { + padding: 3rem !important; + } + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-sm-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-sm-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-sm-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-sm-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-sm-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-sm-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-sm-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-sm-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-sm-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-sm-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-sm-0 { + padding-top: 0 !important; + } + .pt-sm-1 { + padding-top: 0.25rem !important; + } + .pt-sm-2 { + padding-top: 0.5rem !important; + } + .pt-sm-3 { + padding-top: 1rem !important; + } + .pt-sm-4 { + padding-top: 1.5rem !important; + } + .pt-sm-5 { + padding-top: 3rem !important; + } + .pe-sm-0 { + padding-right: 0 !important; + } + .pe-sm-1 { + padding-right: 0.25rem !important; + } + .pe-sm-2 { + padding-right: 0.5rem !important; + } + .pe-sm-3 { + padding-right: 1rem !important; + } + .pe-sm-4 { + padding-right: 1.5rem !important; + } + .pe-sm-5 { + padding-right: 3rem !important; + } + .pb-sm-0 { + padding-bottom: 0 !important; + } + .pb-sm-1 { + padding-bottom: 0.25rem !important; + } + .pb-sm-2 { + padding-bottom: 0.5rem !important; + } + .pb-sm-3 { + padding-bottom: 1rem !important; + } + .pb-sm-4 { + padding-bottom: 1.5rem !important; + } + .pb-sm-5 { + padding-bottom: 3rem !important; + } + .ps-sm-0 { + padding-left: 0 !important; + } + .ps-sm-1 { + padding-left: 0.25rem !important; + } + .ps-sm-2 { + padding-left: 0.5rem !important; + } + .ps-sm-3 { + padding-left: 1rem !important; + } + .ps-sm-4 { + padding-left: 1.5rem !important; + } + .ps-sm-5 { + padding-left: 3rem !important; + } + .gap-sm-0 { + gap: 0 !important; + } + .gap-sm-1 { + gap: 0.25rem !important; + } + .gap-sm-2 { + gap: 0.5rem !important; + } + .gap-sm-3 { + gap: 1rem !important; + } + .gap-sm-4 { + gap: 1.5rem !important; + } + .gap-sm-5 { + gap: 3rem !important; + } + .row-gap-sm-0 { + row-gap: 0 !important; + } + .row-gap-sm-1 { + row-gap: 0.25rem !important; + } + .row-gap-sm-2 { + row-gap: 0.5rem !important; + } + .row-gap-sm-3 { + row-gap: 1rem !important; + } + .row-gap-sm-4 { + row-gap: 1.5rem !important; + } + .row-gap-sm-5 { + row-gap: 3rem !important; + } + .column-gap-sm-0 { + -moz-column-gap: 0 !important; + column-gap: 0 !important; + } + .column-gap-sm-1 { + -moz-column-gap: 0.25rem !important; + column-gap: 0.25rem !important; + } + .column-gap-sm-2 { + -moz-column-gap: 0.5rem !important; + column-gap: 0.5rem !important; + } + .column-gap-sm-3 { + -moz-column-gap: 1rem !important; + column-gap: 1rem !important; + } + .column-gap-sm-4 { + -moz-column-gap: 1.5rem !important; + column-gap: 1.5rem !important; + } + .column-gap-sm-5 { + -moz-column-gap: 3rem !important; + column-gap: 3rem !important; + } + .text-sm-start { + text-align: left !important; + } + .text-sm-end { + text-align: right !important; + } + .text-sm-center { + text-align: center !important; + } +} +@media (min-width: 768px) { + .float-md-start { + float: left !important; + } + .float-md-end { + float: right !important; + } + .float-md-none { + float: none !important; + } + .object-fit-md-contain { + -o-object-fit: contain !important; + object-fit: contain !important; + } + .object-fit-md-cover { + -o-object-fit: cover !important; + object-fit: cover !important; + } + .object-fit-md-fill { + -o-object-fit: fill !important; + object-fit: fill !important; + } + .object-fit-md-scale { + -o-object-fit: scale-down !important; + object-fit: scale-down !important; + } + .object-fit-md-none { + -o-object-fit: none !important; + object-fit: none !important; + } + .d-md-inline { + display: inline !important; + } + .d-md-inline-block { + display: inline-block !important; + } + .d-md-block { + display: block !important; + } + .d-md-grid { + display: grid !important; + } + .d-md-inline-grid { + display: inline-grid !important; + } + .d-md-table { + display: table !important; + } + .d-md-table-row { + display: table-row !important; + } + .d-md-table-cell { + display: table-cell !important; + } + .d-md-flex { + display: flex !important; + } + .d-md-inline-flex { + display: inline-flex !important; + } + .d-md-none { + display: none !important; + } + .flex-md-fill { + flex: 1 1 auto !important; + } + .flex-md-row { + flex-direction: row !important; + } + .flex-md-column { + flex-direction: column !important; + } + .flex-md-row-reverse { + flex-direction: row-reverse !important; + } + .flex-md-column-reverse { + flex-direction: column-reverse !important; + } + .flex-md-grow-0 { + flex-grow: 0 !important; + } + .flex-md-grow-1 { + flex-grow: 1 !important; + } + .flex-md-shrink-0 { + flex-shrink: 0 !important; + } + .flex-md-shrink-1 { + flex-shrink: 1 !important; + } + .flex-md-wrap { + flex-wrap: wrap !important; + } + .flex-md-nowrap { + flex-wrap: nowrap !important; + } + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-md-start { + justify-content: flex-start !important; + } + .justify-content-md-end { + justify-content: flex-end !important; + } + .justify-content-md-center { + justify-content: center !important; + } + .justify-content-md-between { + justify-content: space-between !important; + } + .justify-content-md-around { + justify-content: space-around !important; + } + .justify-content-md-evenly { + justify-content: space-evenly !important; + } + .align-items-md-start { + align-items: flex-start !important; + } + .align-items-md-end { + align-items: flex-end !important; + } + .align-items-md-center { + align-items: center !important; + } + .align-items-md-baseline { + align-items: baseline !important; + } + .align-items-md-stretch { + align-items: stretch !important; + } + .align-content-md-start { + align-content: flex-start !important; + } + .align-content-md-end { + align-content: flex-end !important; + } + .align-content-md-center { + align-content: center !important; + } + .align-content-md-between { + align-content: space-between !important; + } + .align-content-md-around { + align-content: space-around !important; + } + .align-content-md-stretch { + align-content: stretch !important; + } + .align-self-md-auto { + align-self: auto !important; + } + .align-self-md-start { + align-self: flex-start !important; + } + .align-self-md-end { + align-self: flex-end !important; + } + .align-self-md-center { + align-self: center !important; + } + .align-self-md-baseline { + align-self: baseline !important; + } + .align-self-md-stretch { + align-self: stretch !important; + } + .order-md-first { + order: -1 !important; + } + .order-md-0 { + order: 0 !important; + } + .order-md-1 { + order: 1 !important; + } + .order-md-2 { + order: 2 !important; + } + .order-md-3 { + order: 3 !important; + } + .order-md-4 { + order: 4 !important; + } + .order-md-5 { + order: 5 !important; + } + .order-md-last { + order: 6 !important; + } + .m-md-0 { + margin: 0 !important; + } + .m-md-1 { + margin: 0.25rem !important; + } + .m-md-2 { + margin: 0.5rem !important; + } + .m-md-3 { + margin: 1rem !important; + } + .m-md-4 { + margin: 1.5rem !important; + } + .m-md-5 { + margin: 3rem !important; + } + .m-md-auto { + margin: auto !important; + } + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-md-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-md-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-md-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-md-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-md-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-md-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-md-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-md-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-md-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-md-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-md-0 { + margin-top: 0 !important; + } + .mt-md-1 { + margin-top: 0.25rem !important; + } + .mt-md-2 { + margin-top: 0.5rem !important; + } + .mt-md-3 { + margin-top: 1rem !important; + } + .mt-md-4 { + margin-top: 1.5rem !important; + } + .mt-md-5 { + margin-top: 3rem !important; + } + .mt-md-auto { + margin-top: auto !important; + } + .me-md-0 { + margin-right: 0 !important; + } + .me-md-1 { + margin-right: 0.25rem !important; + } + .me-md-2 { + margin-right: 0.5rem !important; + } + .me-md-3 { + margin-right: 1rem !important; + } + .me-md-4 { + margin-right: 1.5rem !important; + } + .me-md-5 { + margin-right: 3rem !important; + } + .me-md-auto { + margin-right: auto !important; + } + .mb-md-0 { + margin-bottom: 0 !important; + } + .mb-md-1 { + margin-bottom: 0.25rem !important; + } + .mb-md-2 { + margin-bottom: 0.5rem !important; + } + .mb-md-3 { + margin-bottom: 1rem !important; + } + .mb-md-4 { + margin-bottom: 1.5rem !important; + } + .mb-md-5 { + margin-bottom: 3rem !important; + } + .mb-md-auto { + margin-bottom: auto !important; + } + .ms-md-0 { + margin-left: 0 !important; + } + .ms-md-1 { + margin-left: 0.25rem !important; + } + .ms-md-2 { + margin-left: 0.5rem !important; + } + .ms-md-3 { + margin-left: 1rem !important; + } + .ms-md-4 { + margin-left: 1.5rem !important; + } + .ms-md-5 { + margin-left: 3rem !important; + } + .ms-md-auto { + margin-left: auto !important; + } + .p-md-0 { + padding: 0 !important; + } + .p-md-1 { + padding: 0.25rem !important; + } + .p-md-2 { + padding: 0.5rem !important; + } + .p-md-3 { + padding: 1rem !important; + } + .p-md-4 { + padding: 1.5rem !important; + } + .p-md-5 { + padding: 3rem !important; + } + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-md-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-md-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-md-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-md-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-md-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-md-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-md-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-md-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-md-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-md-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-md-0 { + padding-top: 0 !important; + } + .pt-md-1 { + padding-top: 0.25rem !important; + } + .pt-md-2 { + padding-top: 0.5rem !important; + } + .pt-md-3 { + padding-top: 1rem !important; + } + .pt-md-4 { + padding-top: 1.5rem !important; + } + .pt-md-5 { + padding-top: 3rem !important; + } + .pe-md-0 { + padding-right: 0 !important; + } + .pe-md-1 { + padding-right: 0.25rem !important; + } + .pe-md-2 { + padding-right: 0.5rem !important; + } + .pe-md-3 { + padding-right: 1rem !important; + } + .pe-md-4 { + padding-right: 1.5rem !important; + } + .pe-md-5 { + padding-right: 3rem !important; + } + .pb-md-0 { + padding-bottom: 0 !important; + } + .pb-md-1 { + padding-bottom: 0.25rem !important; + } + .pb-md-2 { + padding-bottom: 0.5rem !important; + } + .pb-md-3 { + padding-bottom: 1rem !important; + } + .pb-md-4 { + padding-bottom: 1.5rem !important; + } + .pb-md-5 { + padding-bottom: 3rem !important; + } + .ps-md-0 { + padding-left: 0 !important; + } + .ps-md-1 { + padding-left: 0.25rem !important; + } + .ps-md-2 { + padding-left: 0.5rem !important; + } + .ps-md-3 { + padding-left: 1rem !important; + } + .ps-md-4 { + padding-left: 1.5rem !important; + } + .ps-md-5 { + padding-left: 3rem !important; + } + .gap-md-0 { + gap: 0 !important; + } + .gap-md-1 { + gap: 0.25rem !important; + } + .gap-md-2 { + gap: 0.5rem !important; + } + .gap-md-3 { + gap: 1rem !important; + } + .gap-md-4 { + gap: 1.5rem !important; + } + .gap-md-5 { + gap: 3rem !important; + } + .row-gap-md-0 { + row-gap: 0 !important; + } + .row-gap-md-1 { + row-gap: 0.25rem !important; + } + .row-gap-md-2 { + row-gap: 0.5rem !important; + } + .row-gap-md-3 { + row-gap: 1rem !important; + } + .row-gap-md-4 { + row-gap: 1.5rem !important; + } + .row-gap-md-5 { + row-gap: 3rem !important; + } + .column-gap-md-0 { + -moz-column-gap: 0 !important; + column-gap: 0 !important; + } + .column-gap-md-1 { + -moz-column-gap: 0.25rem !important; + column-gap: 0.25rem !important; + } + .column-gap-md-2 { + -moz-column-gap: 0.5rem !important; + column-gap: 0.5rem !important; + } + .column-gap-md-3 { + -moz-column-gap: 1rem !important; + column-gap: 1rem !important; + } + .column-gap-md-4 { + -moz-column-gap: 1.5rem !important; + column-gap: 1.5rem !important; + } + .column-gap-md-5 { + -moz-column-gap: 3rem !important; + column-gap: 3rem !important; + } + .text-md-start { + text-align: left !important; + } + .text-md-end { + text-align: right !important; + } + .text-md-center { + text-align: center !important; + } +} +@media (min-width: 992px) { + .float-lg-start { + float: left !important; + } + .float-lg-end { + float: right !important; + } + .float-lg-none { + float: none !important; + } + .object-fit-lg-contain { + -o-object-fit: contain !important; + object-fit: contain !important; + } + .object-fit-lg-cover { + -o-object-fit: cover !important; + object-fit: cover !important; + } + .object-fit-lg-fill { + -o-object-fit: fill !important; + object-fit: fill !important; + } + .object-fit-lg-scale { + -o-object-fit: scale-down !important; + object-fit: scale-down !important; + } + .object-fit-lg-none { + -o-object-fit: none !important; + object-fit: none !important; + } + .d-lg-inline { + display: inline !important; + } + .d-lg-inline-block { + display: inline-block !important; + } + .d-lg-block { + display: block !important; + } + .d-lg-grid { + display: grid !important; + } + .d-lg-inline-grid { + display: inline-grid !important; + } + .d-lg-table { + display: table !important; + } + .d-lg-table-row { + display: table-row !important; + } + .d-lg-table-cell { + display: table-cell !important; + } + .d-lg-flex { + display: flex !important; + } + .d-lg-inline-flex { + display: inline-flex !important; + } + .d-lg-none { + display: none !important; + } + .flex-lg-fill { + flex: 1 1 auto !important; + } + .flex-lg-row { + flex-direction: row !important; + } + .flex-lg-column { + flex-direction: column !important; + } + .flex-lg-row-reverse { + flex-direction: row-reverse !important; + } + .flex-lg-column-reverse { + flex-direction: column-reverse !important; + } + .flex-lg-grow-0 { + flex-grow: 0 !important; + } + .flex-lg-grow-1 { + flex-grow: 1 !important; + } + .flex-lg-shrink-0 { + flex-shrink: 0 !important; + } + .flex-lg-shrink-1 { + flex-shrink: 1 !important; + } + .flex-lg-wrap { + flex-wrap: wrap !important; + } + .flex-lg-nowrap { + flex-wrap: nowrap !important; + } + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-lg-start { + justify-content: flex-start !important; + } + .justify-content-lg-end { + justify-content: flex-end !important; + } + .justify-content-lg-center { + justify-content: center !important; + } + .justify-content-lg-between { + justify-content: space-between !important; + } + .justify-content-lg-around { + justify-content: space-around !important; + } + .justify-content-lg-evenly { + justify-content: space-evenly !important; + } + .align-items-lg-start { + align-items: flex-start !important; + } + .align-items-lg-end { + align-items: flex-end !important; + } + .align-items-lg-center { + align-items: center !important; + } + .align-items-lg-baseline { + align-items: baseline !important; + } + .align-items-lg-stretch { + align-items: stretch !important; + } + .align-content-lg-start { + align-content: flex-start !important; + } + .align-content-lg-end { + align-content: flex-end !important; + } + .align-content-lg-center { + align-content: center !important; + } + .align-content-lg-between { + align-content: space-between !important; + } + .align-content-lg-around { + align-content: space-around !important; + } + .align-content-lg-stretch { + align-content: stretch !important; + } + .align-self-lg-auto { + align-self: auto !important; + } + .align-self-lg-start { + align-self: flex-start !important; + } + .align-self-lg-end { + align-self: flex-end !important; + } + .align-self-lg-center { + align-self: center !important; + } + .align-self-lg-baseline { + align-self: baseline !important; + } + .align-self-lg-stretch { + align-self: stretch !important; + } + .order-lg-first { + order: -1 !important; + } + .order-lg-0 { + order: 0 !important; + } + .order-lg-1 { + order: 1 !important; + } + .order-lg-2 { + order: 2 !important; + } + .order-lg-3 { + order: 3 !important; + } + .order-lg-4 { + order: 4 !important; + } + .order-lg-5 { + order: 5 !important; + } + .order-lg-last { + order: 6 !important; + } + .m-lg-0 { + margin: 0 !important; + } + .m-lg-1 { + margin: 0.25rem !important; + } + .m-lg-2 { + margin: 0.5rem !important; + } + .m-lg-3 { + margin: 1rem !important; + } + .m-lg-4 { + margin: 1.5rem !important; + } + .m-lg-5 { + margin: 3rem !important; + } + .m-lg-auto { + margin: auto !important; + } + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-lg-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-lg-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-lg-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-lg-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-lg-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-lg-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-lg-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-lg-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-lg-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-lg-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-lg-0 { + margin-top: 0 !important; + } + .mt-lg-1 { + margin-top: 0.25rem !important; + } + .mt-lg-2 { + margin-top: 0.5rem !important; + } + .mt-lg-3 { + margin-top: 1rem !important; + } + .mt-lg-4 { + margin-top: 1.5rem !important; + } + .mt-lg-5 { + margin-top: 3rem !important; + } + .mt-lg-auto { + margin-top: auto !important; + } + .me-lg-0 { + margin-right: 0 !important; + } + .me-lg-1 { + margin-right: 0.25rem !important; + } + .me-lg-2 { + margin-right: 0.5rem !important; + } + .me-lg-3 { + margin-right: 1rem !important; + } + .me-lg-4 { + margin-right: 1.5rem !important; + } + .me-lg-5 { + margin-right: 3rem !important; + } + .me-lg-auto { + margin-right: auto !important; + } + .mb-lg-0 { + margin-bottom: 0 !important; + } + .mb-lg-1 { + margin-bottom: 0.25rem !important; + } + .mb-lg-2 { + margin-bottom: 0.5rem !important; + } + .mb-lg-3 { + margin-bottom: 1rem !important; + } + .mb-lg-4 { + margin-bottom: 1.5rem !important; + } + .mb-lg-5 { + margin-bottom: 3rem !important; + } + .mb-lg-auto { + margin-bottom: auto !important; + } + .ms-lg-0 { + margin-left: 0 !important; + } + .ms-lg-1 { + margin-left: 0.25rem !important; + } + .ms-lg-2 { + margin-left: 0.5rem !important; + } + .ms-lg-3 { + margin-left: 1rem !important; + } + .ms-lg-4 { + margin-left: 1.5rem !important; + } + .ms-lg-5 { + margin-left: 3rem !important; + } + .ms-lg-auto { + margin-left: auto !important; + } + .p-lg-0 { + padding: 0 !important; + } + .p-lg-1 { + padding: 0.25rem !important; + } + .p-lg-2 { + padding: 0.5rem !important; + } + .p-lg-3 { + padding: 1rem !important; + } + .p-lg-4 { + padding: 1.5rem !important; + } + .p-lg-5 { + padding: 3rem !important; + } + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-lg-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-lg-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-lg-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-lg-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-lg-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-lg-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-lg-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-lg-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-lg-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-lg-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-lg-0 { + padding-top: 0 !important; + } + .pt-lg-1 { + padding-top: 0.25rem !important; + } + .pt-lg-2 { + padding-top: 0.5rem !important; + } + .pt-lg-3 { + padding-top: 1rem !important; + } + .pt-lg-4 { + padding-top: 1.5rem !important; + } + .pt-lg-5 { + padding-top: 3rem !important; + } + .pe-lg-0 { + padding-right: 0 !important; + } + .pe-lg-1 { + padding-right: 0.25rem !important; + } + .pe-lg-2 { + padding-right: 0.5rem !important; + } + .pe-lg-3 { + padding-right: 1rem !important; + } + .pe-lg-4 { + padding-right: 1.5rem !important; + } + .pe-lg-5 { + padding-right: 3rem !important; + } + .pb-lg-0 { + padding-bottom: 0 !important; + } + .pb-lg-1 { + padding-bottom: 0.25rem !important; + } + .pb-lg-2 { + padding-bottom: 0.5rem !important; + } + .pb-lg-3 { + padding-bottom: 1rem !important; + } + .pb-lg-4 { + padding-bottom: 1.5rem !important; + } + .pb-lg-5 { + padding-bottom: 3rem !important; + } + .ps-lg-0 { + padding-left: 0 !important; + } + .ps-lg-1 { + padding-left: 0.25rem !important; + } + .ps-lg-2 { + padding-left: 0.5rem !important; + } + .ps-lg-3 { + padding-left: 1rem !important; + } + .ps-lg-4 { + padding-left: 1.5rem !important; + } + .ps-lg-5 { + padding-left: 3rem !important; + } + .gap-lg-0 { + gap: 0 !important; + } + .gap-lg-1 { + gap: 0.25rem !important; + } + .gap-lg-2 { + gap: 0.5rem !important; + } + .gap-lg-3 { + gap: 1rem !important; + } + .gap-lg-4 { + gap: 1.5rem !important; + } + .gap-lg-5 { + gap: 3rem !important; + } + .row-gap-lg-0 { + row-gap: 0 !important; + } + .row-gap-lg-1 { + row-gap: 0.25rem !important; + } + .row-gap-lg-2 { + row-gap: 0.5rem !important; + } + .row-gap-lg-3 { + row-gap: 1rem !important; + } + .row-gap-lg-4 { + row-gap: 1.5rem !important; + } + .row-gap-lg-5 { + row-gap: 3rem !important; + } + .column-gap-lg-0 { + -moz-column-gap: 0 !important; + column-gap: 0 !important; + } + .column-gap-lg-1 { + -moz-column-gap: 0.25rem !important; + column-gap: 0.25rem !important; + } + .column-gap-lg-2 { + -moz-column-gap: 0.5rem !important; + column-gap: 0.5rem !important; + } + .column-gap-lg-3 { + -moz-column-gap: 1rem !important; + column-gap: 1rem !important; + } + .column-gap-lg-4 { + -moz-column-gap: 1.5rem !important; + column-gap: 1.5rem !important; + } + .column-gap-lg-5 { + -moz-column-gap: 3rem !important; + column-gap: 3rem !important; + } + .text-lg-start { + text-align: left !important; + } + .text-lg-end { + text-align: right !important; + } + .text-lg-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .float-xl-start { + float: left !important; + } + .float-xl-end { + float: right !important; + } + .float-xl-none { + float: none !important; + } + .object-fit-xl-contain { + -o-object-fit: contain !important; + object-fit: contain !important; + } + .object-fit-xl-cover { + -o-object-fit: cover !important; + object-fit: cover !important; + } + .object-fit-xl-fill { + -o-object-fit: fill !important; + object-fit: fill !important; + } + .object-fit-xl-scale { + -o-object-fit: scale-down !important; + object-fit: scale-down !important; + } + .object-fit-xl-none { + -o-object-fit: none !important; + object-fit: none !important; + } + .d-xl-inline { + display: inline !important; + } + .d-xl-inline-block { + display: inline-block !important; + } + .d-xl-block { + display: block !important; + } + .d-xl-grid { + display: grid !important; + } + .d-xl-inline-grid { + display: inline-grid !important; + } + .d-xl-table { + display: table !important; + } + .d-xl-table-row { + display: table-row !important; + } + .d-xl-table-cell { + display: table-cell !important; + } + .d-xl-flex { + display: flex !important; + } + .d-xl-inline-flex { + display: inline-flex !important; + } + .d-xl-none { + display: none !important; + } + .flex-xl-fill { + flex: 1 1 auto !important; + } + .flex-xl-row { + flex-direction: row !important; + } + .flex-xl-column { + flex-direction: column !important; + } + .flex-xl-row-reverse { + flex-direction: row-reverse !important; + } + .flex-xl-column-reverse { + flex-direction: column-reverse !important; + } + .flex-xl-grow-0 { + flex-grow: 0 !important; + } + .flex-xl-grow-1 { + flex-grow: 1 !important; + } + .flex-xl-shrink-0 { + flex-shrink: 0 !important; + } + .flex-xl-shrink-1 { + flex-shrink: 1 !important; + } + .flex-xl-wrap { + flex-wrap: wrap !important; + } + .flex-xl-nowrap { + flex-wrap: nowrap !important; + } + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-xl-start { + justify-content: flex-start !important; + } + .justify-content-xl-end { + justify-content: flex-end !important; + } + .justify-content-xl-center { + justify-content: center !important; + } + .justify-content-xl-between { + justify-content: space-between !important; + } + .justify-content-xl-around { + justify-content: space-around !important; + } + .justify-content-xl-evenly { + justify-content: space-evenly !important; + } + .align-items-xl-start { + align-items: flex-start !important; + } + .align-items-xl-end { + align-items: flex-end !important; + } + .align-items-xl-center { + align-items: center !important; + } + .align-items-xl-baseline { + align-items: baseline !important; + } + .align-items-xl-stretch { + align-items: stretch !important; + } + .align-content-xl-start { + align-content: flex-start !important; + } + .align-content-xl-end { + align-content: flex-end !important; + } + .align-content-xl-center { + align-content: center !important; + } + .align-content-xl-between { + align-content: space-between !important; + } + .align-content-xl-around { + align-content: space-around !important; + } + .align-content-xl-stretch { + align-content: stretch !important; + } + .align-self-xl-auto { + align-self: auto !important; + } + .align-self-xl-start { + align-self: flex-start !important; + } + .align-self-xl-end { + align-self: flex-end !important; + } + .align-self-xl-center { + align-self: center !important; + } + .align-self-xl-baseline { + align-self: baseline !important; + } + .align-self-xl-stretch { + align-self: stretch !important; + } + .order-xl-first { + order: -1 !important; + } + .order-xl-0 { + order: 0 !important; + } + .order-xl-1 { + order: 1 !important; + } + .order-xl-2 { + order: 2 !important; + } + .order-xl-3 { + order: 3 !important; + } + .order-xl-4 { + order: 4 !important; + } + .order-xl-5 { + order: 5 !important; + } + .order-xl-last { + order: 6 !important; + } + .m-xl-0 { + margin: 0 !important; + } + .m-xl-1 { + margin: 0.25rem !important; + } + .m-xl-2 { + margin: 0.5rem !important; + } + .m-xl-3 { + margin: 1rem !important; + } + .m-xl-4 { + margin: 1.5rem !important; + } + .m-xl-5 { + margin: 3rem !important; + } + .m-xl-auto { + margin: auto !important; + } + .mx-xl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-xl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-xl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-xl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-xl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-xl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-xl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-xl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-xl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-xl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-xl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-xl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-xl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-xl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-xl-0 { + margin-top: 0 !important; + } + .mt-xl-1 { + margin-top: 0.25rem !important; + } + .mt-xl-2 { + margin-top: 0.5rem !important; + } + .mt-xl-3 { + margin-top: 1rem !important; + } + .mt-xl-4 { + margin-top: 1.5rem !important; + } + .mt-xl-5 { + margin-top: 3rem !important; + } + .mt-xl-auto { + margin-top: auto !important; + } + .me-xl-0 { + margin-right: 0 !important; + } + .me-xl-1 { + margin-right: 0.25rem !important; + } + .me-xl-2 { + margin-right: 0.5rem !important; + } + .me-xl-3 { + margin-right: 1rem !important; + } + .me-xl-4 { + margin-right: 1.5rem !important; + } + .me-xl-5 { + margin-right: 3rem !important; + } + .me-xl-auto { + margin-right: auto !important; + } + .mb-xl-0 { + margin-bottom: 0 !important; + } + .mb-xl-1 { + margin-bottom: 0.25rem !important; + } + .mb-xl-2 { + margin-bottom: 0.5rem !important; + } + .mb-xl-3 { + margin-bottom: 1rem !important; + } + .mb-xl-4 { + margin-bottom: 1.5rem !important; + } + .mb-xl-5 { + margin-bottom: 3rem !important; + } + .mb-xl-auto { + margin-bottom: auto !important; + } + .ms-xl-0 { + margin-left: 0 !important; + } + .ms-xl-1 { + margin-left: 0.25rem !important; + } + .ms-xl-2 { + margin-left: 0.5rem !important; + } + .ms-xl-3 { + margin-left: 1rem !important; + } + .ms-xl-4 { + margin-left: 1.5rem !important; + } + .ms-xl-5 { + margin-left: 3rem !important; + } + .ms-xl-auto { + margin-left: auto !important; + } + .p-xl-0 { + padding: 0 !important; + } + .p-xl-1 { + padding: 0.25rem !important; + } + .p-xl-2 { + padding: 0.5rem !important; + } + .p-xl-3 { + padding: 1rem !important; + } + .p-xl-4 { + padding: 1.5rem !important; + } + .p-xl-5 { + padding: 3rem !important; + } + .px-xl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-xl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-xl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-xl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-xl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-xl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-xl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-xl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-xl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-xl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-xl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-xl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-xl-0 { + padding-top: 0 !important; + } + .pt-xl-1 { + padding-top: 0.25rem !important; + } + .pt-xl-2 { + padding-top: 0.5rem !important; + } + .pt-xl-3 { + padding-top: 1rem !important; + } + .pt-xl-4 { + padding-top: 1.5rem !important; + } + .pt-xl-5 { + padding-top: 3rem !important; + } + .pe-xl-0 { + padding-right: 0 !important; + } + .pe-xl-1 { + padding-right: 0.25rem !important; + } + .pe-xl-2 { + padding-right: 0.5rem !important; + } + .pe-xl-3 { + padding-right: 1rem !important; + } + .pe-xl-4 { + padding-right: 1.5rem !important; + } + .pe-xl-5 { + padding-right: 3rem !important; + } + .pb-xl-0 { + padding-bottom: 0 !important; + } + .pb-xl-1 { + padding-bottom: 0.25rem !important; + } + .pb-xl-2 { + padding-bottom: 0.5rem !important; + } + .pb-xl-3 { + padding-bottom: 1rem !important; + } + .pb-xl-4 { + padding-bottom: 1.5rem !important; + } + .pb-xl-5 { + padding-bottom: 3rem !important; + } + .ps-xl-0 { + padding-left: 0 !important; + } + .ps-xl-1 { + padding-left: 0.25rem !important; + } + .ps-xl-2 { + padding-left: 0.5rem !important; + } + .ps-xl-3 { + padding-left: 1rem !important; + } + .ps-xl-4 { + padding-left: 1.5rem !important; + } + .ps-xl-5 { + padding-left: 3rem !important; + } + .gap-xl-0 { + gap: 0 !important; + } + .gap-xl-1 { + gap: 0.25rem !important; + } + .gap-xl-2 { + gap: 0.5rem !important; + } + .gap-xl-3 { + gap: 1rem !important; + } + .gap-xl-4 { + gap: 1.5rem !important; + } + .gap-xl-5 { + gap: 3rem !important; + } + .row-gap-xl-0 { + row-gap: 0 !important; + } + .row-gap-xl-1 { + row-gap: 0.25rem !important; + } + .row-gap-xl-2 { + row-gap: 0.5rem !important; + } + .row-gap-xl-3 { + row-gap: 1rem !important; + } + .row-gap-xl-4 { + row-gap: 1.5rem !important; + } + .row-gap-xl-5 { + row-gap: 3rem !important; + } + .column-gap-xl-0 { + -moz-column-gap: 0 !important; + column-gap: 0 !important; + } + .column-gap-xl-1 { + -moz-column-gap: 0.25rem !important; + column-gap: 0.25rem !important; + } + .column-gap-xl-2 { + -moz-column-gap: 0.5rem !important; + column-gap: 0.5rem !important; + } + .column-gap-xl-3 { + -moz-column-gap: 1rem !important; + column-gap: 1rem !important; + } + .column-gap-xl-4 { + -moz-column-gap: 1.5rem !important; + column-gap: 1.5rem !important; + } + .column-gap-xl-5 { + -moz-column-gap: 3rem !important; + column-gap: 3rem !important; + } + .text-xl-start { + text-align: left !important; + } + .text-xl-end { + text-align: right !important; + } + .text-xl-center { + text-align: center !important; + } +} +@media (min-width: 1400px) { + .float-xxl-start { + float: left !important; + } + .float-xxl-end { + float: right !important; + } + .float-xxl-none { + float: none !important; + } + .object-fit-xxl-contain { + -o-object-fit: contain !important; + object-fit: contain !important; + } + .object-fit-xxl-cover { + -o-object-fit: cover !important; + object-fit: cover !important; + } + .object-fit-xxl-fill { + -o-object-fit: fill !important; + object-fit: fill !important; + } + .object-fit-xxl-scale { + -o-object-fit: scale-down !important; + object-fit: scale-down !important; + } + .object-fit-xxl-none { + -o-object-fit: none !important; + object-fit: none !important; + } + .d-xxl-inline { + display: inline !important; + } + .d-xxl-inline-block { + display: inline-block !important; + } + .d-xxl-block { + display: block !important; + } + .d-xxl-grid { + display: grid !important; + } + .d-xxl-inline-grid { + display: inline-grid !important; + } + .d-xxl-table { + display: table !important; + } + .d-xxl-table-row { + display: table-row !important; + } + .d-xxl-table-cell { + display: table-cell !important; + } + .d-xxl-flex { + display: flex !important; + } + .d-xxl-inline-flex { + display: inline-flex !important; + } + .d-xxl-none { + display: none !important; + } + .flex-xxl-fill { + flex: 1 1 auto !important; + } + .flex-xxl-row { + flex-direction: row !important; + } + .flex-xxl-column { + flex-direction: column !important; + } + .flex-xxl-row-reverse { + flex-direction: row-reverse !important; + } + .flex-xxl-column-reverse { + flex-direction: column-reverse !important; + } + .flex-xxl-grow-0 { + flex-grow: 0 !important; + } + .flex-xxl-grow-1 { + flex-grow: 1 !important; + } + .flex-xxl-shrink-0 { + flex-shrink: 0 !important; + } + .flex-xxl-shrink-1 { + flex-shrink: 1 !important; + } + .flex-xxl-wrap { + flex-wrap: wrap !important; + } + .flex-xxl-nowrap { + flex-wrap: nowrap !important; + } + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-xxl-start { + justify-content: flex-start !important; + } + .justify-content-xxl-end { + justify-content: flex-end !important; + } + .justify-content-xxl-center { + justify-content: center !important; + } + .justify-content-xxl-between { + justify-content: space-between !important; + } + .justify-content-xxl-around { + justify-content: space-around !important; + } + .justify-content-xxl-evenly { + justify-content: space-evenly !important; + } + .align-items-xxl-start { + align-items: flex-start !important; + } + .align-items-xxl-end { + align-items: flex-end !important; + } + .align-items-xxl-center { + align-items: center !important; + } + .align-items-xxl-baseline { + align-items: baseline !important; + } + .align-items-xxl-stretch { + align-items: stretch !important; + } + .align-content-xxl-start { + align-content: flex-start !important; + } + .align-content-xxl-end { + align-content: flex-end !important; + } + .align-content-xxl-center { + align-content: center !important; + } + .align-content-xxl-between { + align-content: space-between !important; + } + .align-content-xxl-around { + align-content: space-around !important; + } + .align-content-xxl-stretch { + align-content: stretch !important; + } + .align-self-xxl-auto { + align-self: auto !important; + } + .align-self-xxl-start { + align-self: flex-start !important; + } + .align-self-xxl-end { + align-self: flex-end !important; + } + .align-self-xxl-center { + align-self: center !important; + } + .align-self-xxl-baseline { + align-self: baseline !important; + } + .align-self-xxl-stretch { + align-self: stretch !important; + } + .order-xxl-first { + order: -1 !important; + } + .order-xxl-0 { + order: 0 !important; + } + .order-xxl-1 { + order: 1 !important; + } + .order-xxl-2 { + order: 2 !important; + } + .order-xxl-3 { + order: 3 !important; + } + .order-xxl-4 { + order: 4 !important; + } + .order-xxl-5 { + order: 5 !important; + } + .order-xxl-last { + order: 6 !important; + } + .m-xxl-0 { + margin: 0 !important; + } + .m-xxl-1 { + margin: 0.25rem !important; + } + .m-xxl-2 { + margin: 0.5rem !important; + } + .m-xxl-3 { + margin: 1rem !important; + } + .m-xxl-4 { + margin: 1.5rem !important; + } + .m-xxl-5 { + margin: 3rem !important; + } + .m-xxl-auto { + margin: auto !important; + } + .mx-xxl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-xxl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-xxl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-xxl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-xxl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-xxl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-xxl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-xxl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-xxl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-xxl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-xxl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-xxl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-xxl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-xxl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-xxl-0 { + margin-top: 0 !important; + } + .mt-xxl-1 { + margin-top: 0.25rem !important; + } + .mt-xxl-2 { + margin-top: 0.5rem !important; + } + .mt-xxl-3 { + margin-top: 1rem !important; + } + .mt-xxl-4 { + margin-top: 1.5rem !important; + } + .mt-xxl-5 { + margin-top: 3rem !important; + } + .mt-xxl-auto { + margin-top: auto !important; + } + .me-xxl-0 { + margin-right: 0 !important; + } + .me-xxl-1 { + margin-right: 0.25rem !important; + } + .me-xxl-2 { + margin-right: 0.5rem !important; + } + .me-xxl-3 { + margin-right: 1rem !important; + } + .me-xxl-4 { + margin-right: 1.5rem !important; + } + .me-xxl-5 { + margin-right: 3rem !important; + } + .me-xxl-auto { + margin-right: auto !important; + } + .mb-xxl-0 { + margin-bottom: 0 !important; + } + .mb-xxl-1 { + margin-bottom: 0.25rem !important; + } + .mb-xxl-2 { + margin-bottom: 0.5rem !important; + } + .mb-xxl-3 { + margin-bottom: 1rem !important; + } + .mb-xxl-4 { + margin-bottom: 1.5rem !important; + } + .mb-xxl-5 { + margin-bottom: 3rem !important; + } + .mb-xxl-auto { + margin-bottom: auto !important; + } + .ms-xxl-0 { + margin-left: 0 !important; + } + .ms-xxl-1 { + margin-left: 0.25rem !important; + } + .ms-xxl-2 { + margin-left: 0.5rem !important; + } + .ms-xxl-3 { + margin-left: 1rem !important; + } + .ms-xxl-4 { + margin-left: 1.5rem !important; + } + .ms-xxl-5 { + margin-left: 3rem !important; + } + .ms-xxl-auto { + margin-left: auto !important; + } + .p-xxl-0 { + padding: 0 !important; + } + .p-xxl-1 { + padding: 0.25rem !important; + } + .p-xxl-2 { + padding: 0.5rem !important; + } + .p-xxl-3 { + padding: 1rem !important; + } + .p-xxl-4 { + padding: 1.5rem !important; + } + .p-xxl-5 { + padding: 3rem !important; + } + .px-xxl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-xxl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-xxl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-xxl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-xxl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-xxl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-xxl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-xxl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-xxl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-xxl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-xxl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-xxl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-xxl-0 { + padding-top: 0 !important; + } + .pt-xxl-1 { + padding-top: 0.25rem !important; + } + .pt-xxl-2 { + padding-top: 0.5rem !important; + } + .pt-xxl-3 { + padding-top: 1rem !important; + } + .pt-xxl-4 { + padding-top: 1.5rem !important; + } + .pt-xxl-5 { + padding-top: 3rem !important; + } + .pe-xxl-0 { + padding-right: 0 !important; + } + .pe-xxl-1 { + padding-right: 0.25rem !important; + } + .pe-xxl-2 { + padding-right: 0.5rem !important; + } + .pe-xxl-3 { + padding-right: 1rem !important; + } + .pe-xxl-4 { + padding-right: 1.5rem !important; + } + .pe-xxl-5 { + padding-right: 3rem !important; + } + .pb-xxl-0 { + padding-bottom: 0 !important; + } + .pb-xxl-1 { + padding-bottom: 0.25rem !important; + } + .pb-xxl-2 { + padding-bottom: 0.5rem !important; + } + .pb-xxl-3 { + padding-bottom: 1rem !important; + } + .pb-xxl-4 { + padding-bottom: 1.5rem !important; + } + .pb-xxl-5 { + padding-bottom: 3rem !important; + } + .ps-xxl-0 { + padding-left: 0 !important; + } + .ps-xxl-1 { + padding-left: 0.25rem !important; + } + .ps-xxl-2 { + padding-left: 0.5rem !important; + } + .ps-xxl-3 { + padding-left: 1rem !important; + } + .ps-xxl-4 { + padding-left: 1.5rem !important; + } + .ps-xxl-5 { + padding-left: 3rem !important; + } + .gap-xxl-0 { + gap: 0 !important; + } + .gap-xxl-1 { + gap: 0.25rem !important; + } + .gap-xxl-2 { + gap: 0.5rem !important; + } + .gap-xxl-3 { + gap: 1rem !important; + } + .gap-xxl-4 { + gap: 1.5rem !important; + } + .gap-xxl-5 { + gap: 3rem !important; + } + .row-gap-xxl-0 { + row-gap: 0 !important; + } + .row-gap-xxl-1 { + row-gap: 0.25rem !important; + } + .row-gap-xxl-2 { + row-gap: 0.5rem !important; + } + .row-gap-xxl-3 { + row-gap: 1rem !important; + } + .row-gap-xxl-4 { + row-gap: 1.5rem !important; + } + .row-gap-xxl-5 { + row-gap: 3rem !important; + } + .column-gap-xxl-0 { + -moz-column-gap: 0 !important; + column-gap: 0 !important; + } + .column-gap-xxl-1 { + -moz-column-gap: 0.25rem !important; + column-gap: 0.25rem !important; + } + .column-gap-xxl-2 { + -moz-column-gap: 0.5rem !important; + column-gap: 0.5rem !important; + } + .column-gap-xxl-3 { + -moz-column-gap: 1rem !important; + column-gap: 1rem !important; + } + .column-gap-xxl-4 { + -moz-column-gap: 1.5rem !important; + column-gap: 1.5rem !important; + } + .column-gap-xxl-5 { + -moz-column-gap: 3rem !important; + column-gap: 3rem !important; + } + .text-xxl-start { + text-align: left !important; + } + .text-xxl-end { + text-align: right !important; + } + .text-xxl-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .fs-1 { + font-size: 2.5rem !important; + } + .fs-2 { + font-size: 2rem !important; + } + .fs-3 { + font-size: 1.75rem !important; + } + .fs-4 { + font-size: 1.5rem !important; + } +} +@media print { + .d-print-inline { + display: inline !important; + } + .d-print-inline-block { + display: inline-block !important; + } + .d-print-block { + display: block !important; + } + .d-print-grid { + display: grid !important; + } + .d-print-inline-grid { + display: inline-grid !important; + } + .d-print-table { + display: table !important; + } + .d-print-table-row { + display: table-row !important; + } + .d-print-table-cell { + display: table-cell !important; + } + .d-print-flex { + display: flex !important; + } + .d-print-inline-flex { + display: inline-flex !important; + } + .d-print-none { + display: none !important; + } +} +.navbar { + font-size: 0.875rem; + font-weight: 500; +} +.navbar .nav-item { + margin-right: 0.5rem; + margin-left: 0.5rem; +} +.navbar .navbar-nav .nav-link { + border-radius: 0.375rem; +} + +.navbar-dark .navbar-nav .nav-link:hover { + background-color: rgba(255, 255, 255, 0.1); +} +.navbar-dark .navbar-nav .nav-link.active { + background-color: rgba(0, 0, 0, 0.5); +} + +.navbar-light .navbar-nav .nav-link:hover { + background-color: rgba(0, 0, 0, 0.03); +} +.navbar-light .navbar-nav .nav-link.active { + background-color: rgba(0, 0, 0, 0.05); +} + +.navbar-nav { + --bs-nav-link-padding-x: .5rem; +} + +.btn-secondary, +.btn-light, +.btn-outline-secondary, +.btn-outline-light { + color: #212529; +} +.btn-secondary:disabled, .btn-secondary.disabled, +.btn-light:disabled, +.btn-light.disabled, +.btn-outline-secondary:disabled, +.btn-outline-secondary.disabled, +.btn-outline-light:disabled, +.btn-outline-light.disabled { + border: 1px solid #e6e6e6; +} + +.btn-secondary, +.btn-outline-secondary { + border-color: #e6e6e6; +} +.btn-secondary:hover, .btn-secondary:active, +.btn-outline-secondary:hover, +.btn-outline-secondary:active { + background-color: #e6e6e6; + border-color: #e6e6e6; +} + +.btn-light, +.btn-outline-light { + border-color: #dfe0e1; +} +.btn-light:hover, .btn-light:active, +.btn-outline-light:hover, +.btn-outline-light:active { + background-color: #dfe0e1; + border-color: #dfe0e1; +} + +.table { + font-size: 0.875rem; + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); +} + +thead th { + font-size: 0.875rem; + text-transform: uppercase; +} + +.input-group-text { + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.nav-tabs { + font-weight: 500; +} +.nav-tabs .nav-link { + padding-top: 1rem; + padding-bottom: 1rem; + border-width: 0 0 1px; +} +.nav-tabs .nav-link.active, +.nav-tabs .nav-item.show .nav-link { + box-shadow: inset 0 -2px 0 #3459e6; +} + +.nav-pills { + font-weight: 500; +} + +.pagination { + font-size: 0.875rem; + font-weight: 500; +} +.pagination .page-link { + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.breadcrumb { + font-size: 0.875rem; + font-weight: 500; + border: 1px solid var(--bs-secondary-bg); + border-radius: 0.375rem; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} +.breadcrumb-item { + padding: 1rem 0.5rem 1rem 0; +} + +.breadcrumb-item + .breadcrumb-item::before { + padding-right: 1rem; +} + +.alert .btn-close { + color: inherit; +} + +.badge.bg-secondary, .badge.bg-light { + color: #212529; +} + +.list-group-item h1, +.list-group-item h2, +.list-group-item h3, +.list-group-item h4, +.list-group-item h5, +.list-group-item h6, +.list-group-item .h1, +.list-group-item .h2, +.list-group-item .h3, +.list-group-item .h4, +.list-group-item .h5, +.list-group-item .h6, +.card h1, +.card h2, +.card h3, +.card h4, +.card h5, +.card h6, +.card .h1, +.card .h2, +.card .h3, +.card .h4, +.card .h5, +.card .h6 { + color: inherit; +} + +.list-group { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); +} + +.card { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); +} + +.modal-footer { + background-color: var(--bs-tertiary-bg); +} + +.modal-content { + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); +} diff --git a/VisualPinball.Unity/Documentation~/template/vpe/token.json b/VisualPinball.Unity/Documentation~/template/vpe/token.json index 310ea224e..b249f391f 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/token.json +++ b/VisualPinball.Unity/Documentation~/template/vpe/token.json @@ -1,3 +1,3 @@ { - "improveThisDoc": "Improve this Doc" + "improveThisDoc": "Improve this Page" } From 36a520e9ba72df38610897910c50d259d7a7133c Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Oct 2023 01:36:07 +0200 Subject: [PATCH 126/159] doc: Use latest GitHub docfx generator. --- .github/workflows/documentation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index b4d7731b5..2203585f1 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -8,7 +8,7 @@ jobs: name: Build and publish documentation steps: - uses: actions/checkout@v3 - - uses: nikeee/docfx-action@v1.0.0 + - uses: nunit/docfx-action@v2.4.0 name: Build Documentation with: args: VisualPinball.Unity/Documentation~/docfx.json From f1e959c9166b458d4b15ecad807ee1724daf138e Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Oct 2023 02:15:59 +0200 Subject: [PATCH 127/159] doc: Use GitHub for zephyr.css and center landing art. --- VisualPinball.Unity/Documentation~/index.md | 294 +++++++++--------- .../template/vpe/public/main.css | 20 +- 2 files changed, 161 insertions(+), 153 deletions(-) diff --git a/VisualPinball.Unity/Documentation~/index.md b/VisualPinball.Unity/Documentation~/index.md index c00db95a4..2ecc932be 100644 --- a/VisualPinball.Unity/Documentation~/index.md +++ b/VisualPinball.Unity/Documentation~/index.md @@ -8,154 +8,154 @@ is_full: true
Welcome to the documentation of the - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - VISUAL PINBALL ENGINE + diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css index f4ce4db98..29f45b10d 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -1,5 +1,5 @@ @import url("fonts.css"); -@import url("zephyr.css"); +@import url("https://github.com/thomaspark/bootswatch/raw/v5/dist/zephyr/bootstrap.min.css"); /* layout */ .navbar-github { /* align github link to the right */ @@ -23,14 +23,14 @@ body[data-layout=landing]>main { /* landing page full width */ [data-bs-theme=light] { --bs-font-sans-serif: Inter, 'Segoe UI', Tahoma, Helvetica, sans-serif; --bs-body-font-family: var(--bs-font-sans-serif); - --bs-link-color-rgb: 214, 99, 22; - --bs-link-hover-color-rgb: 183, 74, 0; + --bs-link-color-rgb: 214, 99, 22 !important; + --bs-link-hover-color-rgb: 183, 74, 0 !important; --vpe-body-bg-secondary: #f3f3f3; --vpe-link-secondary: #00000080; --vpe-link-secondary-hover: #000000aa; } [data-bs-theme=dark] { - --bs-link-color-rgb: 236, 132, 61; + --bs-link-color-rgb: 236, 132, 61 !important; --vpe-body-bg-secondary: #292e33; --vpe-link-secondary: #ffffff80; --vpe-link-secondary-hover: #ffffffaa; @@ -40,7 +40,15 @@ body[data-layout=landing]>main { /* landing page full width */ background-color: var(--vpe-body-bg-secondary) !important; } -/* don't underline links */ +[data-bs-theme=light] header .dropdown a:hover, +[data-bs-theme=light] header .dropdown a:active, +[data-bs-theme=light] header .dropdown a:focus-visible, +[data-bs-theme=light] header .dropdown a:focus, +[data-bs-theme=light] header .btn.show { + color: white !important; +} + + /* don't underline links */ a { text-decoration: none !important; } @@ -76,7 +84,7 @@ svg .cls-2, .cls-3, .cls-4 { /* outer */ svg .cls-3 { /* logo */ fill: var(--bs-body-color); } -svg .cls-4 { +svg .cls-4 { /* inner */ fill: var(--vpe-body-bg-secondary); } From 807cc8812c825b4752661a4f8a3ca0f93ca8af46 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Oct 2023 12:24:24 +0200 Subject: [PATCH 128/159] doc: More color and margin fixes. --- .../Documentation~/favicon.ico | Bin 0 -> 15406 bytes .../template/vpe/public/main.css | 114 +++++------------- .../template/vpe/public/zephyr.css | 4 + .../Documentation~/template/vpe/token.json | 3 +- 4 files changed, 36 insertions(+), 85 deletions(-) create mode 100644 VisualPinball.Unity/Documentation~/favicon.ico diff --git a/VisualPinball.Unity/Documentation~/favicon.ico b/VisualPinball.Unity/Documentation~/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8e856771e7b50bfd5c6c34b822e435f7ab520114 GIT binary patch literal 15406 zcmeI32auIT62~8+a)vuWk|bGj5OB#Nh-9!Rlpq#z5)MQt5QOst3aLU#2Z91e4n=tg zC|H1iSQa1#f*`>o3JaVBl?)=84SoOL@V@7_Z(TRIkKL=elb_c>;mCs*8>eelHscY|0-9lvf*dQIA{odZekC zS($Cyw#DdKF-;wVjlcc&+vP=y6tOK^wyaKTf6;9A!V53h%$YN-ef#$MX-}sXhuYq` zV#SKRJ$m$@pY`qA*FOC4!-IOgJ2g12UAxw|Ns}h_HL|KztJ?VS<1gxa!QaDieX%EzI_%O8*Bah_qTfW z>RI{nOwmWz3w4Z+Z$;y>0XG@kWvBr%X+bgfUVjq3#fnz4 zWJx=B?p&Pes$>-Yl<;W0OGk|wWqI=Caq!w}uOWkVDfP>U?;2;LqeqWgp+beMb?esF zsZ%G*pFh9b&-ATbM$kwOhw$grICrteJ(?abZQ8WaXZx=pv~MPdC%yHe-Fw4^4I!CB zkTP=QNLQ!*il0N$i~slf32z?looCq_gE|K-SEP%EE>^2njs5$Q_$>T;xYF}YgeJZF z?z?WBvu4c-QvUU^Xwf3~4I7{`FFiDp>mz&>WlL_BDO1Mk)T!fa$gh-dy=lzWv}sc- zR;(EICPB5elf#$Rdg1=`_19l_<6F0GT_V!hY-~4BxNu?D=H-`Prp;!-AGRaH(F*%s zpg;lZ*s&vc6O~=NcDXgkIt1$0t!sJn=CvI=cF?X@m+h_nZ|hSkMk1 zKAed5Z~eg57cE-Unm2E5@$vCEYJc(LOv}4y|6}#))lR0vh7AjmL*MbGk}L1L^N#B? zd-iPh#jS!4YKtFGQ;;h)Jg84W`F0m;)vD!uCj1(&j2JP(qN1Yg%$YM@mBG_zpMB=w zlTSWz`{RQTK4^XV^s$dW{@Bo)-Me>NTwEN!<^**l1W2~%`{7TOzB==;Wm^W`8a>4J8`Yi@jU+whi)A5WE|623tk+II5JG;HNMT-_r z&(J@w96Wf?7<+O+%z&>8Z$pO;g$Ft(@%>f5e!zeMhWzCFdg$$|ufB492MrqJ{9a<1 zmMvR?C)6gTmzy_lTDNZ99G+phyz#~x%xkD^N-yYAi4rB84=;LOd-T=sUj07Ws#Pnum*CrbW$xU$j#iZ_RjhmW z?hcp>);c^;k6rY>g+F`s>g8nS;iD~krRZJt(H}-E0KTzf$9hd&j8n5_O~*5Qrw7WG zEo+KdLpXc(?CJIt(T{_^p2ZYfU3v7;N3C+@$}Y|dHO}A{^f@{@+Qk{78xy3zkl2c` z6CXvgC=PXWSl^;QUbN~ercGeqBrYQciv+Mf2M!$Q)>V)Wdr@K0-@<$__S*p+I&@$S z-4xx{$X?Hj!-o$yY-}U}yMSHPnA!UpK%2t5>Lx@QL}!=)JCySl&1Hv!IUf9*f_CEGX)eh|++bePZ@Bu?q2cmteSjgjixTY&K`mSFT*aQU8}9VrL*3Aqw$V zNwPl7IWa!I=W}46}4XzNbpptTqP8wUFRzU~rh%OfTYnr1FLFoLj&jc|`JI{&M#0 zS!>(2t^3Y78fPska|D^XmPJ2Wvb;=Qj&pbPhVuabxeSbIj4pO9Uc9)Q2jW?s8MByM zWYz?Tr~5>I&GF;MUA`6Blh35BO0Q24gSeWICPu#Q|aXAAH{t|(k@{Jit7J~nRL zIM<%DM$X+-w?k0mcIuH>>5fmsehBa6H-c+25z8AlZge{J*kg~G2ai1Ri0eZ?)_PFi zhN|OjS<9kRLUKONSrY4!^K;fC=a1ns@P^MN>7>b08Yz+2;HAL)M~q z?;@Okesi`oVZww&fIo+C&3HI(A~zts!r6jxmti(wtrtl8%Ci=#lU~AXu#X8ws50LYKTxxZY@8r0UFBatQfG_;^A8^lQd=$%aW}~W)(z*b z*bn?Z>>oCS^L^Uj`{BdlcZ-J@A;M2AtY@lYX|-j|jv}`}-U2$rBjhstg*-)5LhR{We1bVz9oYIBcZ zhIAp}@y8!`bf0+Q370nsF{KyojiEE}gMQ&lKogsc-{UXrmG~UYPilbkdvcZF1V8(= z?)fnW;^}&VWcMq5t1p?I8Z%~$>r37*m>UbRB-`WmKl}mmM#S#$4K3EVKTj9xl!h1a z>HP8O)2F+&1zu#xJ}5Mc1WE4IF)ymmp}y-GE4n~G=AL}4zX*?$3E#Q5!v4vct5m6y z>qE{hT-W^lQ~QqYAv^A9K#RKo!V5D=?jxuU-g`0k$P!)PejYKFzrYvyQt;sm`1e!d zEYCja?x4GW=kJ@IclIIHGV2}reD~dV=+T7mbs*g3RKH*MNFCqs$37Qst2S-gtXy?6z@lfxuJ~?pbP$@KF;qU7U6rOfO#Wc@E6t__6KZ|uw$Uwi>?E8$;HV#5D$hK5Z?cbHXZog$qNrC@b-g zyjhPgz4VfCk5u_Ie1=)#S^qI|tLS|{u>}4B@k3St&WDIA+4Iq3@p(+VcNX05@y=7f z>+0Jk!2v-`7K1(F2VMD_;9fu9{&#&NXPY|+2u(9 literal 0 HcmV?d00001 diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css index 29f45b10d..936a1fbc8 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -10,7 +10,6 @@ .navbar-github > svg { /* github logo color */ fill: #ccc; } - body[data-layout=landing]>main { /* landing page full width */ display: block; } @@ -19,27 +18,31 @@ body[data-layout=landing]>main { /* landing page full width */ display: block; } +/* color overrides */ :root, [data-bs-theme=light] { --bs-font-sans-serif: Inter, 'Segoe UI', Tahoma, Helvetica, sans-serif; --bs-body-font-family: var(--bs-font-sans-serif); --bs-link-color-rgb: 214, 99, 22 !important; --bs-link-hover-color-rgb: 183, 74, 0 !important; + --bs-code-color: #d6b933; --vpe-body-bg-secondary: #f3f3f3; --vpe-link-secondary: #00000080; --vpe-link-secondary-hover: #000000aa; + --vpe-body-color-less-contrast: rgba(33, 37, 41, 0.5) } [data-bs-theme=dark] { --bs-link-color-rgb: 236, 132, 61 !important; --vpe-body-bg-secondary: #292e33; --vpe-link-secondary: #ffffff80; --vpe-link-secondary-hover: #ffffffaa; + --vpe-body-color-less-contrast: rgba(222, 226, 230, 0.5) } - [data-bs-theme=dark] header { /* header slightly lighter in dark mode */ background-color: var(--vpe-body-bg-secondary) !important; } +/* fix theme toggle button color */ [data-bs-theme=light] header .dropdown a:hover, [data-bs-theme=light] header .dropdown a:active, [data-bs-theme=light] header .dropdown a:focus-visible, @@ -48,29 +51,29 @@ body[data-layout=landing]>main { /* landing page full width */ color: white !important; } - /* don't underline links */ +/* don't underline links */ a { text-decoration: none !important; } /* zephyr fixes */ -.btn-outline-secondary { +.btn-outline-secondary { /* outline button */ color: var(--bs-secondary-color) !important; } -[data-bs-theme=dark] .btn-outline-secondary:hover { +[data-bs-theme=dark] .btn-outline-secondary:hover { /* outline button hover */ color: var(--bs-body-bg) !important; } -.link-secondary { +.link-secondary { /* TOC links on the left */ color: var(--vpe-link-secondary) !important; } .link-secondary:hover { color: var(--vpe-link-secondary-hover) !important; } -#search-results > .sr-items .sr-item > .item-href { +#search-results > .sr-items .sr-item > .item-href { /* search result colors */ color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); } - /* landing logo colors */ +/* landing svg art colors */ svg .cls-1 { /* visual pinball engine */ fill: var(--bs-body-color); font-family: Asgalt-Regular, Asgalt; @@ -78,7 +81,7 @@ svg .cls-1 { /* visual pinball engine */ letter-spacing: .19em; } svg .cls-2, .cls-3, .cls-4 { /* outer */ - stroke-width: 0px; + stroke-width: 0; fill: var(--bs-body-bg) } svg .cls-3 { /* logo */ @@ -88,85 +91,28 @@ svg .cls-4 { /* inner */ fill: var(--vpe-body-bg-secondary); } -.border-top:not(.next-article) { /* footer background color */ +/* footer customization */ +body>footer, body[data-layout=landing]>footer { /* footer height */ + color: var(--vpe-body-color-less-contrast) !important; background-color: var(--vpe-body-bg-secondary); + font-size: 0.8rem !important; + height: 52px; + padding-left: 10px; } -/*body > main {*/ -/* padding-top: 0;*/ -/*}*/ - -/*article {*/ -/* margin-top: 20px;*/ -/*}*/ - -/*main > .toc-offcanvas {*/ -/* background-color: #efefef;*/ -/* padding: 15px;*/ -/* top: calc(35px + 1.6rem) !important;*/ -/* max-height: calc(100vh - 35px - 1.6rem) !important;*/ -/*}*/ - -/*!* fonts *!*/ -/*html,*/ -/*body {*/ -/* font-family: Inter, 'Segoe UI', Tahoma, Helvetica, sans-serif;*/ -/* font-size: 100%;*/ -/*}*/ - - +/* make titles bold */ h1, h2 { font-weight: bold; } -/*.affix h5 { !* "In this article" *!*/ -/* font-weight: 600;*/ -/* letter-spacing: normal !important;*/ -/*}*/ - -/*header .btn:hover {*/ -/* background-color: #fff;*/ -/*}*/ - -/*.btn.btn-default.active, .btn.btn-default:active {*/ -/* outline: 0;*/ -/* -webkit-box-shadow: none;*/ -/* box-shadow: none;*/ -/* background-color: rgba(1,1,1,0.08);*/ -/*}*/ - -/*.navbar-brand > svg {*/ -/* margin-top: 6px;*/ -/*}*/ - - - -/*.navbar-default {*/ -/* background-color: rgba(1,1,1,0.05);*/ -/* border-color: rgba(1,1,1,0.1);*/ -/*}*/ - -/*#sidetoc .sidefilter {*/ -/* top: 94px;*/ -/*}*/ - -/*#sidetoc .sidetoc.shiftup {*/ -/* bottom: 0;*/ -/*}*/ - -/*img[alt="Visual Pinball Engine"] {*/ -/* margin-top: 15px;*/ -/*}*/ - -/*.table-bordered,*/ -/*.table-bordered>tbody>tr>td,*/ -/*.table-bordered>tbody>tr>th,*/ -/*.table-bordered>tfoot>tr>td,*/ -/*.table-bordered>tfoot>tr>th,*/ -/*.table-bordered>thead>tr>td,*/ -/*.table-bordered>thead>tr>th {*/ -/* border-color: rgba(1,1,1,0.15);*/ -/*}*/ -/*.table-striped > tbody > tr:nth-of-type(odd) {*/ -/* background-color: rgba(1,1,1,0.03)*/ -/*}*/ +/* make tables striped */ +table.table.table-bordered > tbody > tr:nth-of-type(odd) > td { + background-color: var(--vpe-body-bg-secondary); +} +table.table.table-bordered > thead > tr > th { /* separate column header */ + border-bottom-width: 3px; +} +table.table.table-bordered > * > tr > *:nth-child(1) { /* separate row header */ + border-right-width: 3px; + font-style: italic; +} diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/zephyr.css b/VisualPinball.Unity/Documentation~/template/vpe/public/zephyr.css index 94dc11023..732b3c4ca 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/zephyr.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/zephyr.css @@ -1,3 +1,7 @@ +/* this is just for reference. inlcuded is the minified version directly from github. + * https://github.com/thomaspark/bootswatch/tree/v5/dist/zephyr + */ + @charset "UTF-8"; /*! * Bootswatch v5.3.2 (https://bootswatch.com) diff --git a/VisualPinball.Unity/Documentation~/template/vpe/token.json b/VisualPinball.Unity/Documentation~/template/vpe/token.json index b249f391f..203df6dd8 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/token.json +++ b/VisualPinball.Unity/Documentation~/template/vpe/token.json @@ -1,3 +1,4 @@ { - "improveThisDoc": "Improve this Page" + "improveThisDoc": "Improve this Page", + "inThisArticle": "Table of Contents" } From 9f576f9392025e5c47dc56569684e9484c18e2e5 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Oct 2023 12:30:39 +0200 Subject: [PATCH 129/159] doc: Fix code color style. --- .../Documentation~/template/vpe/public/main.css | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css index 936a1fbc8..51a874a3c 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -25,7 +25,7 @@ body[data-layout=landing]>main { /* landing page full width */ --bs-body-font-family: var(--bs-font-sans-serif); --bs-link-color-rgb: 214, 99, 22 !important; --bs-link-hover-color-rgb: 183, 74, 0 !important; - --bs-code-color: #d6b933; + --bs-code-color: rgb(var(--bs-link-color-rgb), 1); --vpe-body-bg-secondary: #f3f3f3; --vpe-link-secondary: #00000080; --vpe-link-secondary-hover: #000000aa; @@ -70,7 +70,7 @@ a { color: var(--vpe-link-secondary-hover) !important; } #search-results > .sr-items .sr-item > .item-href { /* search result colors */ - color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); + color: rgba(var(--bs-link-color-rgb), 0.6); } /* landing svg art colors */ @@ -116,3 +116,10 @@ table.table.table-bordered > * > tr > *:nth-child(1) { /* separate row header */ border-right-width: 3px; font-style: italic; } + +/* code colors */ +code { + background-color: rgb(var(--bs-link-color-rgb), 0.15); + padding: 1px 3px; + border-radius: 3px; +} From 441e1ec14638d1345fd97065a7b024ae8116e712 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Oct 2023 18:01:10 +0200 Subject: [PATCH 130/159] doc: Add lightbox. --- .../partials/scripts.tmpl.partial | 7 ------- .../styles/plugin-featherlight.js | 15 --------------- .../template/vpe/layout/_master.tmpl | 14 ++++++++++++++ .../template/vpe/public/basicLightbox.min.css | 1 + .../template/vpe/public/basicLightbox.min.js | 1 + .../Documentation~/template/vpe/public/main.css | 7 ++++++- 6 files changed, 22 insertions(+), 23 deletions(-) delete mode 100644 VisualPinball.Unity/Documentation~/template/lightbox-featherlight/partials/scripts.tmpl.partial delete mode 100644 VisualPinball.Unity/Documentation~/template/lightbox-featherlight/styles/plugin-featherlight.js create mode 100644 VisualPinball.Unity/Documentation~/template/vpe/public/basicLightbox.min.css create mode 100644 VisualPinball.Unity/Documentation~/template/vpe/public/basicLightbox.min.js diff --git a/VisualPinball.Unity/Documentation~/template/lightbox-featherlight/partials/scripts.tmpl.partial b/VisualPinball.Unity/Documentation~/template/lightbox-featherlight/partials/scripts.tmpl.partial deleted file mode 100644 index 16b384b48..000000000 --- a/VisualPinball.Unity/Documentation~/template/lightbox-featherlight/partials/scripts.tmpl.partial +++ /dev/null @@ -1,7 +0,0 @@ -{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}} - - - - - - diff --git a/VisualPinball.Unity/Documentation~/template/lightbox-featherlight/styles/plugin-featherlight.js b/VisualPinball.Unity/Documentation~/template/lightbox-featherlight/styles/plugin-featherlight.js deleted file mode 100644 index f4283ebe8..000000000 --- a/VisualPinball.Unity/Documentation~/template/lightbox-featherlight/styles/plugin-featherlight.js +++ /dev/null @@ -1,15 +0,0 @@ -$(document).ready(function() { - //find all images, but not the logo, and add the lightbox - $('img').not('.logo').each(function(){ - var $img = $(this); - var filename = $img.attr('src') - //add cursor - $img.css('cursor','zoom-in'); - $img.css('cursor','-moz-zoom-in'); - $img.css('cursor','-webkit-zoom-in'); - - //add featherlight - $img.attr('alt', filename); - $img.featherlight(filename); - }); -}); \ No newline at end of file diff --git a/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl b/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl index 5fd021ba4..f6bc52f5f 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl +++ b/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl @@ -18,6 +18,7 @@ {{#_noindex}}{{/_noindex}} @@ -163,6 +164,19 @@
+ + + {{/redirect_url}} diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/basicLightbox.min.css b/VisualPinball.Unity/Documentation~/template/vpe/public/basicLightbox.min.css new file mode 100644 index 000000000..175b1ce3a --- /dev/null +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/basicLightbox.min.css @@ -0,0 +1 @@ +.basicLightbox{position:fixed;display:flex;justify-content:center;align-items:center;top:0;left:0;width:100%;height:100vh;background:rgba(0,0,0,.8);opacity:.01;transition:opacity .4s ease;z-index:1000;will-change:opacity}.basicLightbox--visible{opacity:1}.basicLightbox__placeholder{max-width:100%;transform:scale(.9);transition:transform .4s ease;z-index:1;will-change:transform}.basicLightbox__placeholder>iframe:first-child:last-child,.basicLightbox__placeholder>img:first-child:last-child,.basicLightbox__placeholder>video:first-child:last-child{display:block;position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;max-width:95%;max-height:95%}.basicLightbox__placeholder>iframe:first-child:last-child,.basicLightbox__placeholder>video:first-child:last-child{pointer-events:auto}.basicLightbox__placeholder>img:first-child:last-child,.basicLightbox__placeholder>video:first-child:last-child{width:auto;height:auto}.basicLightbox--iframe .basicLightbox__placeholder,.basicLightbox--img .basicLightbox__placeholder,.basicLightbox--video .basicLightbox__placeholder{width:100%;height:100%;pointer-events:none}.basicLightbox--visible .basicLightbox__placeholder{transform:scale(1)} \ No newline at end of file diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/basicLightbox.min.js b/VisualPinball.Unity/Documentation~/template/vpe/public/basicLightbox.min.js new file mode 100644 index 000000000..b2b6ccd57 --- /dev/null +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/basicLightbox.min.js @@ -0,0 +1 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).basicLightbox=e()}}((function(){return function e(n,t,o){function r(c,u){if(!t[c]){if(!n[c]){var s="function"==typeof require&&require;if(!u&&s)return s(c,!0);if(i)return i(c,!0);var a=new Error("Cannot find module '"+c+"'");throw a.code="MODULE_NOT_FOUND",a}var l=t[c]={exports:{}};n[c][0].call(l.exports,(function(e){return r(n[c][1][e]||e)}),l,l.exports,e,n,t,o)}return t[c].exports}for(var i="function"==typeof require&&require,c=0;c1&&void 0!==arguments[1]&&arguments[1],t=document.createElement("div");return t.innerHTML=e.trim(),!0===n?t.children:t.firstChild},r=function(e,n){var t=e.children;return 1===t.length&&t[0].tagName===n},i=function(e){return null!=(e=e||document.querySelector(".basicLightbox"))&&!0===e.ownerDocument.body.contains(e)};t.visible=i;t.create=function(e,n){var t=function(e,n){var t=o('\n\t\t
\n\t\t\t\n\t\t
\n\t')),i=t.querySelector(".basicLightbox__placeholder");e.forEach((function(e){return i.appendChild(e)}));var c=r(i,"IMG"),u=r(i,"VIDEO"),s=r(i,"IFRAME");return!0===c&&t.classList.add("basicLightbox--img"),!0===u&&t.classList.add("basicLightbox--video"),!0===s&&t.classList.add("basicLightbox--iframe"),t}(e=function(e){var n="string"==typeof e,t=e instanceof HTMLElement==1;if(!1===n&&!1===t)throw new Error("Content must be a DOM element/node or string");return!0===n?Array.from(o(e,!0)):"TEMPLATE"===e.tagName?[e.content.cloneNode(!0)]:Array.from(e.children)}(e),n=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(null==(e=Object.assign({},e)).closable&&(e.closable=!0),null==e.className&&(e.className=""),null==e.onShow&&(e.onShow=function(){}),null==e.onClose&&(e.onClose=function(){}),"boolean"!=typeof e.closable)throw new Error("Property `closable` must be a boolean");if("string"!=typeof e.className)throw new Error("Property `className` must be a string");if("function"!=typeof e.onShow)throw new Error("Property `onShow` must be a function");if("function"!=typeof e.onClose)throw new Error("Property `onClose` must be a function");return e}(n)),c=function(e){return!1!==n.onClose(u)&&function(e,n){return e.classList.remove("basicLightbox--visible"),setTimeout((function(){return!1===i(e)||e.parentElement.removeChild(e),n()}),410),!0}(t,(function(){if("function"==typeof e)return e(u)}))};!0===n.closable&&t.addEventListener("click",(function(e){e.target===t&&c()}));var u={element:function(){return t},visible:function(){return i(t)},show:function(e){return!1!==n.onShow(u)&&function(e,n){return document.body.appendChild(e),setTimeout((function(){requestAnimationFrame((function(){return e.classList.add("basicLightbox--visible"),n()}))}),10),!0}(t,(function(){if("function"==typeof e)return e(u)}))},close:c};return u}},{}]},{},[1])(1)})); \ No newline at end of file diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css index 51a874a3c..bd1eaa6b9 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -1,5 +1,5 @@ @import url("fonts.css"); -@import url("https://github.com/thomaspark/bootswatch/raw/v5/dist/zephyr/bootstrap.min.css"); +@import url("https://raw.githubusercontent.com/thomaspark/bootswatch/v5/dist/zephyr/bootstrap.min.css"); /* layout */ .navbar-github { /* align github link to the right */ @@ -123,3 +123,8 @@ code { padding: 1px 3px; border-radius: 3px; } + +/* image hover cursor */ +img:not(#logo):hover { + cursor: zoom-in; +} From a199a3144b4adecf573e27afa053e19977a01e29 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Oct 2023 18:13:24 +0200 Subject: [PATCH 131/159] doc: Fix image classes. --- .../editor/advanced/camera-settings.md | 2 +- .../Documentation~/creators-guide/manual/displays.md | 4 ++-- .../manual/mechanisms/collision-switches.md | 2 +- .../manual/mechanisms/drop-target-banks.md | 2 +- .../creators-guide/manual/mechanisms/flippers.md | 2 +- .../manual/mechanisms/lifting-gates.md | 6 +++--- .../creators-guide/manual/mechanisms/light-groups.md | 2 +- .../creators-guide/manual/mechanisms/rotators.md | 2 +- .../creators-guide/manual/mechanisms/score-motors.md | 6 +++--- .../creators-guide/manual/mechanisms/score-reels.md | 10 +++++----- .../creators-guide/manual/mechanisms/slingshots.md | 4 ++-- .../creators-guide/manual/mechanisms/teleporters.md | 2 +- .../creators-guide/manual/mechanisms/troughs.md | 12 ++++++------ .../creators-guide/setup/running-vpe.md | 2 +- .../realistic-backglass/1-prepare-artwork.md | 2 +- .../realistic-plastics/1-prepare-artwork.md | 4 ++-- .../tutorials/realistic-plastics/3-uv-map-mesh.md | 4 ++-- .../realistic-plastics/4-import-into-unity.md | 2 +- .../tutorials/realistic-playfield/1-textures.md | 2 +- .../realistic-playfield/4-import-into-unity.md | 2 +- .../Documentation~/plugins/pinmame/mechs.md | 2 +- .../plugins/visual-scripting/complementary-usage.md | 2 +- .../Documentation~/plugins/visual-scripting/setup.md | 10 +++++----- .../plugins/visual-scripting/variables.md | 2 +- 24 files changed, 45 insertions(+), 45 deletions(-) diff --git a/VisualPinball.Unity/Documentation~/creators-guide/editor/advanced/camera-settings.md b/VisualPinball.Unity/Documentation~/creators-guide/editor/advanced/camera-settings.md index 52bc9bf35..9b9d5798e 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/editor/advanced/camera-settings.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/editor/advanced/camera-settings.md @@ -13,7 +13,7 @@ The camera controller is setup to orbit around a focal point. While doing this i ## Usage - + To use the camera controller, select the `Camera` scene object, which is at the very top of the hierarchy. In the inspector you will find a few sliders: diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/displays.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/displays.md index 7c74e1779..df986e776 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/displays.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/displays.md @@ -23,13 +23,13 @@ For example, in [MPF](xref:mpf_index) you name your displays yourself in the mac ### Editor -Add display component +Add display component VPE provides three display components, a [score reel](xref:score-reels), a segment display and a DMD. Both the segment display and the DMD component create the underlying geometry and apply a shader that renders the content of the display. In order to create one, make an empty game object in your scene and add the desired component under *Visual Pinball -> Display*. You can also create the game object with a component already assigned by right-clicking in the hierarchy and choosing *Visual Pinball -> Dot Matrix Display*. This will place the display into your scene right behind your playfield. -DMD Inspector +DMD Inspector Selecting the game object will let you customize it in the inspector, and assign the ID that links it to the gamelogic engine. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/collision-switches.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/collision-switches.md index d0483bd09..63389e314 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/collision-switches.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/collision-switches.md @@ -14,7 +14,7 @@ To create a Collision Switch: - Add the collision switch directly to a hittable game object. Select the game object you want to add it to, click on *Add Component* in the inspector and select *Visual Pinball -> Mechs -> Collision Switch*. - + To associate the collision switch with a game logic engine switch, use the [Switch Manager](xref:switch_manager) and select the switch in the *Element* column: diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/drop-target-banks.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/drop-target-banks.md index f5e48cea7..e36bdd6a4 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/drop-target-banks.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/drop-target-banks.md @@ -15,7 +15,7 @@ You can create a Drop Target Bank in two different ways. 1. If your game has a single bank drop target, or multiple single bank drop targets, it is preferred to add it directly to the drop target. Select the drop target you want to add it to, click on *Add Component* in the inspector and select *Visual Pinball -> Mechs -> Drop Target Bank*. 2. If your game has drop target banks with multiple drop targets, click on *Drop Target Bank* in the toolbox. This will add a *Drop Target Banks* hierarchy to the playfield and create a new GameObject with the right component assigned. - + To configure the drop target bank, select the total number of drop targets from the *Banks* drop down. Then, under *Playfield Links*, select each drop target belonging to the bank. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/flippers.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/flippers.md index 5ecd0009c..1da781e92 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/flippers.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/flippers.md @@ -20,7 +20,7 @@ It's possible to provide a custom mesh for the flipper by replacing the game obj ### Physics -Flipper Collider +Flipper Collider Adding the *Flipper Collider* component to the flipper makes it part of the physics simulation. Here you can tweak the various parameters. Most of the following is taken directly from [Mukuste's Wiki](https://github.com/c-f-h/vpinball/wiki/VP10-Physics#flipper-parameters). diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/lifting-gates.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/lifting-gates.md index 91177bbaf..a76436dfb 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/lifting-gates.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/lifting-gates.md @@ -6,7 +6,7 @@ description: This component makes your gate toggelable by a coil. It works by li # Lifting Gates -
+

Photo © 2022 by bord @@ -18,7 +18,7 @@ VPE provides a component that you can add to your existing gate. By doing that, ## Setup - + In order to add the lifting gate feature to a gate, select the game object of the gate and click on *Add Component* in the inspector. Select it by searching or navigating to *Visual Pinball -> Mechs -> Gate Lifter*. @@ -35,4 +35,4 @@ How fast the gate rotates from and into the decativated position. Higher is fast Adding the gate lifter component adds a coil input to the gate, i.e. you can map it to any of the gamelogic engine's coil outputs through the [Coil Manager](xref:coil_manager). > [!NOTE] -> If you're working on an EM game or an original game with [Visual Scripting](xref:uvs_index), don't forget to add the new coil to the [coil definitions](xref:uvs_setup#coils). \ No newline at end of file +> If you're working on an EM game or an original game with [Visual Scripting](xref:uvs_index), don't forget to add the new coil to the [coil definitions](xref:uvs_setup#coils). diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/light-groups.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/light-groups.md index 1312452bf..ac9c364e2 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/light-groups.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/light-groups.md @@ -12,7 +12,7 @@ A light group is a component you can add to any GameObject. It's recommended to ## Setup - + To create a new light group, select the GameObject you want to add your light group to, and in the inspector click on *Add Component* and choose *Visual Pinball -> Game Item -> Light Group*. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/rotators.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/rotators.md index eda42327f..1a4451d2b 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/rotators.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/rotators.md @@ -12,7 +12,7 @@ Sometimes during gameplay, you might need to rotate objects in order to recreate ## Setup -Rotator Inspector +Rotator Inspector In order to create a rotator, add the **Rotator** component to a game object by clicking *Add Component* in the inspector, then choosing *Visual Pinball -> Game Item -> Rotator*. You can use any game object, although we recommend adding it to the target that you want to rotate. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/score-motors.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/score-motors.md index 27d920d36..b88d467e4 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/score-motors.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/score-motors.md @@ -37,7 +37,7 @@ To setup a score motor, select any game object, click on *Add Component* in the Next, configure the score motor. The inspector shows the following options: - + - **Steps** defines how many steps the score motor pulses for one turn. - **Duration** defines the length of time it takes the score motor to completely cycle. @@ -47,7 +47,7 @@ Next, configure the score motor. The inspector shows the following options: > [!NOTE] > The minimum amount of `Steps` for a score motor is `5`. `Increase by 5` will not be shown under `Reel timing by increase` if `Steps` is set to 5, as all actions would be `Increase`. - + By default, the score motor is configured to: @@ -94,4 +94,4 @@ In order to hook into those switches, you'll have to create them in the GLE insp -Then, in your graphs, add your logic behind the corresponding [On Switch Changed](xref:uvs_node_reference#on-switch-changed) node(s). \ No newline at end of file +Then, in your graphs, add your logic behind the corresponding [On Switch Changed](xref:uvs_node_reference#on-switch-changed) node(s). diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/score-reels.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/score-reels.md index a265fe57b..9eadb016d 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/score-reels.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/score-reels.md @@ -6,7 +6,7 @@ description: How to use EM-style reels to display the score. # Score Reel Displays -Score Reels a of a Gottlieb Volley +Score Reels a of a Gottlieb Volley In electro-mechanical games, score reels are very common for displaying the player score. Typically, four to six units are mounted behind the backglass. Each reel is driven by a coil that advances the reel by one position when pulsed. The coils are driven by the playfield elements in the game, often indirectly through a score motor for multi-point scoring. @@ -39,7 +39,7 @@ In your scene, drop in your reel model and add the *Score Reel* component (not t #### Score Reel -Score Reel Inspector +Score Reel Inspector The *Score Reel* component is quick to set up. There is only one option, which is the *rotation direction*. What the score reel component gets from the display component is "turn to position X", where X is between 0 and 9, and the component's job is to animate the reel to that position. @@ -47,7 +47,7 @@ Internally, it also takes in the rotation speed, and how long it rests at the fi #### Score Reel Display -Score Reel Display Inspector +Score Reel Display Inspector This is the component on the parent game object that receives score numbers from the game and tells the individual reels to which position they need to turn to. @@ -62,7 +62,7 @@ This is the component on the parent game object that receives score numbers from ### Gamelogic Engine -Score Reel Display Inspector +Score Reel Display Inspector Score reels are primarily used in EMs, so they are typically driven by [Visual Scripting](xref:uvs_index). As with every display, the first step is to define the display in the GLE component. @@ -74,4 +74,4 @@ Next, add *Numeric* under *Supported Formats*. In Visual Scripting, use the [Update Display](xref:uvs_node_reference#update-display) node to set a new score. It's up to you whether to use a separate [event](xref:uvs_setup#events) or to subscribe to a [player variable](xref:uvs_variables) directly. -If you're using a score motor, read how to set it up correctly [here](xref:score-motors#usage). \ No newline at end of file +If you're using a score motor, read how to set it up correctly [here](xref:score-motors#usage). diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/slingshots.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/slingshots.md index 9e12add05..c6785146c 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/slingshots.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/slingshots.md @@ -15,7 +15,7 @@ VPE does provide a slingshot component that implements the rubber animation duri # Setup -Slingshot Inspector +Slingshot Inspector ### Slingshot Wall @@ -34,7 +34,7 @@ To set the start and end positions of the control points, we reference two rubbe On physical machines, the rubber is moved by an arm attached to the coil. VPE can simulate the movement of that arm by rotating a primitive across the X-axis. In the *Coil Arm* field, a reference to the primive can be set, and the total angle of rotation under *Arm Angle*. -Slingshot Animation Curve +Slingshot Animation Curve ### Animation diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/teleporters.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/teleporters.md index 77397bffe..7c2e42eb2 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/teleporters.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/teleporters.md @@ -15,7 +15,7 @@ Sometimes it's easier to teleport the ball from one place to another instead of ## Setup -Teleporter Inspector +Teleporter Inspector In order to create a new teleporter, select the GameObject you want to add it to, click on *Add Component* and select *Visual Pinball -> Game Item -> Teleporter*. You can choose any GameObject, although we recommend putting it on same GameObject as the source kicker. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/troughs.md b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/troughs.md index 3d9de9d4b..4b91ae7c9 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/troughs.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/manual/mechanisms/troughs.md @@ -16,7 +16,7 @@ When importing a `.vpx` file that doesn't have any troughs (which is likely, bec ## Linking to the Playfield - + To interact with the game, you must set up an **input switch** to drain the ball into the trough, and an **exit kicker** to release a new ball from the trough. This terminology may seem weird, since the ball *exits* the playfield when draining, but from the trough's perspective, that's where the ball *enters*. @@ -44,7 +44,7 @@ In this section we'll again link to the excellent MPF documentation explaining e ### Modern Mechanical - + [Modern troughs with mechanical switches](https://missionpinball.org/mechs/troughs/#option-2-modern-trough-with-mechanical-switches) are covered by this type. @@ -54,7 +54,7 @@ The ball drains from the playfield directly into the ball stack, and every ball ### Modern Opto - + [Modern troughs with optical switches](https://missionpinball.org/mechs/troughs/#option-1-modern-trough-with-opto-sensors) work similar similar to their mechanical counterparts. However there are two differences: @@ -70,7 +70,7 @@ We call this closing time the *transition time* - it's the time during stack tra ### Two coils and multiple switches - + [Troughs of this type](https://missionpinball.org/mechs/troughs/#option-3-older-style-with-two-coils-and-switches-for-each-ball) can be found in older machines from the 80s and early 90s. They consist of two parts: @@ -83,7 +83,7 @@ In terms of switches, they still include a switch per ball in the stack, but als ### Two coils and one switch - + A trough can also have [only one switch](https://missionpinball.org/mechs/troughs/#option-4-older-style-with-two-coils-and-only-one-ball-switch) in the ball stack. @@ -93,7 +93,7 @@ Instead of a *Switch Count* like the previous types, you select a *Switch Positi ### Classic single ball - + A single ball trough may work [with](https://missionpinball.org/mechs/troughs/#option-5-classic-single-ball-single-coil) or [without](https://missionpinball.org/mechs/troughs/#option-6-classic-single-ball-single-coil-no-shooter-lane) a shooter lane. The principle is simple: After draining, the ball is kept on the drain coil, which ejects the ball either directly into the plunger lane or back onto the playfield. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/setup/running-vpe.md b/VisualPinball.Unity/Documentation~/creators-guide/setup/running-vpe.md index b98909be1..35b3235a1 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/setup/running-vpe.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/setup/running-vpe.md @@ -19,7 +19,7 @@ Now that we have the camera of the scene view somewhat aligned, we still can't s ![Imported blank table](unity-imported-table-ugly-gizmos.png) -Gizmo Size +Gizmo Size These orange artifacts are what Unity calls [Gizmo Icons](https://docs.unity3d.com/Manual/GizmosMenu.html). They are enabled by default, and since VPE uses icons for its playfield elements, they are all over the place. Unity's default gizmo size is adapted for rather large scenes and we're dealing with a pinball table, let's make them smaller by clicking on the gizmo icon in the *Scene* view, and pull the size *3D Icons* slider down until you're happy. You can additionally hide the VPE icons by clicking on *Visual Pinball -> Editor -> Disable Gizmo Icons*. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-backglass/1-prepare-artwork.md b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-backglass/1-prepare-artwork.md index e6f7e4445..6a65a2d5e 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-backglass/1-prepare-artwork.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-backglass/1-prepare-artwork.md @@ -16,7 +16,7 @@ Once you have your artwork secured save this as a PNG file. We'll name it `Backg ## Create the Thickness Mask - + To block the passage of light through the backglass we need to make a thickness map layer. This layer consists of pure white for the areas that are opaque and pure black for the areas that are transparent. If you have physical access to the backglass then you can scan the backside to get this mask. Otherwise, you'll have to trace what's visible on the front, and try to reconstruct elements that aren't. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/1-prepare-artwork.md b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/1-prepare-artwork.md index 5cc59bb12..6dca3596b 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/1-prepare-artwork.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/1-prepare-artwork.md @@ -63,7 +63,7 @@ Note the *Links* toolbox that shows the individual plastic files. Also note the ## Step 3: Export Texture and Outlines - + We'll first export the texture. In Illustrator, click on *File -> Export -> Export As...*, and make sure *Use Artboards* is checked. As type, select *PNG*. Then, enter `Plastics.png` as file name and click on *Export*, which will result in the dialog seen in the screenshot. @@ -87,7 +87,7 @@ Your document should now look like this: Don't worry about the color, it just needs to be filled in any color. I'm using magenta because it gives a good contrast to the rest of the artwork. - + Click on *File -> Save a Copy...*, enter `Plastics.svg` as file name, save as type *SVG* and make sure *Use Artboards* is unchecked this time. Click on *Save*. In the options panel, click on *More Options* and make sure all the options are disabled as shown in the screenshot. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/3-uv-map-mesh.md b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/3-uv-map-mesh.md index 04853325d..cab044901 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/3-uv-map-mesh.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/3-uv-map-mesh.md @@ -11,7 +11,7 @@ description: How to UV-map the texture onto your mesh in Blender We need three material slots, for the top and bottom faces, as well as for the edges. We'll split the vertices by firstly assigning everything to an "edge" slot, and then re-assigning the top and bottom faces to their own slots. - + In object mode, open *Materials* properties and remove the current material slot (hit `-`). Add three new slots (press 3× `+`), and for each slot, create a new material by hitting the *New* button when the slot is selected. Name them "top", "bottom" and "edge" and set their base color to red, green, and blue respectively. Your slots should now look like in the screenshot. @@ -21,7 +21,7 @@ Then, press `7` on the numpad to switch to top view, zoom in a bit so you can cl ![Triangle selected](blender-triangle-selected-2.png) - + Click on *Select -> Select Similar -> Coplanar*, which should result in all top faces of all plastics being selected (but *not* the bottoms ones). However, you might get the bottom faces selected too, because there's a threshold that might be too large. You can check it by rotating the camera and verify that the bottom faces are not selected. If they are, expand the parameters and set the threshold to a small enough value. Then, select the "top" material slot and hit *Assign*. The top surfaces should turn red. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/4-import-into-unity.md b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/4-import-into-unity.md index 6f6d1ecb0..45f2121ee 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/4-import-into-unity.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-plastics/4-import-into-unity.md @@ -23,7 +23,7 @@ We recommend unpacking the prefab. Unpacking will still reference the meshes of First, let's configure how the texture is imported. In the *Project* window, navigate to `Assets//Textures` where you saved `Plastics.png`, and select it. In the *Inspector* window, check the option *Alpha Is Transparent*. Depending on how large you've exported it, you might need to update *Max Size* as well, in our case we'll use 4096 × 4096. When you're done, hit *Apply* at the bottom. - + Next, we'll create a material of our bottom surface. In the *Project* window, navigate to `Packages/Visual Pinball Engine (HDRP)/Assets/Art/Materials/Default/Plastic`, select `Plastics Decal`, hit `Ctrl`+`C`. Navigate to your project's `Assets/
/Materials` folder, and press `Ctrl`+`V`. diff --git a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-playfield/1-textures.md b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-playfield/1-textures.md index a133342fd..cf0ef45d7 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-playfield/1-textures.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-playfield/1-textures.md @@ -10,7 +10,7 @@ In this first step, we'll go through how to create the various textures that we ## Texture Layout - + The geometry of the playfield has three different areas: diff --git a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-playfield/4-import-into-unity.md b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-playfield/4-import-into-unity.md index a383b0b15..0b47c20e5 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-playfield/4-import-into-unity.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/tutorials/realistic-playfield/4-import-into-unity.md @@ -15,7 +15,7 @@ First, let's bring our files into the Unity project. There are four files that g While the import options for the FBX file are fine, we need to adjust them for the textures. - + Select the base texture and change the following options in the *Inspector*: diff --git a/VisualPinball.Unity/Documentation~/plugins/pinmame/mechs.md b/VisualPinball.Unity/Documentation~/plugins/pinmame/mechs.md index 5a3462b8c..970f82b46 100644 --- a/VisualPinball.Unity/Documentation~/plugins/pinmame/mechs.md +++ b/VisualPinball.Unity/Documentation~/plugins/pinmame/mechs.md @@ -34,7 +34,7 @@ This page is about approach #2 and describes how you can configure and use PinMA ## Setup -PinMAME Mech Inspector +PinMAME Mech Inspector PinMAME can simulate up to five custom mechs. You create one by adding the *PinMAME Mech* component onto a game object. diff --git a/VisualPinball.Unity/Documentation~/plugins/visual-scripting/complementary-usage.md b/VisualPinball.Unity/Documentation~/plugins/visual-scripting/complementary-usage.md index 06877aa0f..b79fb45b8 100644 --- a/VisualPinball.Unity/Documentation~/plugins/visual-scripting/complementary-usage.md +++ b/VisualPinball.Unity/Documentation~/plugins/visual-scripting/complementary-usage.md @@ -14,7 +14,7 @@ In this case, we'd like to keep PinMAME as the driving GLE, but add a visual scr ## Setup -Visual Scripting Bridge +Visual Scripting Bridge In order to give VPE's visual scripting nodes access to your game logic engine, we provide what we call a *Visual Scripting Bridge*. It's a component that you'll need to add to your table's game object, along with your original gamelogic engine. You can do that by selecting the game object, clicking *Add Component* in the inspector, and choosing *Visual Pinball -> Gamelogic Engine -> Visual Scripting Game Logic*. diff --git a/VisualPinball.Unity/Documentation~/plugins/visual-scripting/setup.md b/VisualPinball.Unity/Documentation~/plugins/visual-scripting/setup.md index 8cca136d7..42622ce48 100644 --- a/VisualPinball.Unity/Documentation~/plugins/visual-scripting/setup.md +++ b/VisualPinball.Unity/Documentation~/plugins/visual-scripting/setup.md @@ -18,7 +18,7 @@ So instead of interacting with playfield items directly, you need to define the ### Displays -Display Configuration +Display Configuration The first configuration you'll see in the inspector is which type of displays your game expects to find on the playfield. You can have multiple displays. For each display, you define the size and which type of formats it must be able to handle. These are the possible types: @@ -33,19 +33,19 @@ The display components that VPE provides understand multiple formats, e.g., our ### Switches -Switch Definitions +Switch Definitions In this section you define the switches that appear in the [Switch Manager](xref:switch_manager) when you auto-populate them. It's also the source for all the [switch-related nodes](xref:uvs_node_reference#switches) that VPE provides within your visual scripting graphs. ### Coils -Coil Definitions +Coil Definitions Here you define your coils. Same concept as for switches. These are the coils you'll see in the [Coil Manager](xref:coil_manager), and they are the source when looking up IDs in visual scripting's [coil nodes](xref:uvs_node_reference#coils). ### Lamps -Lamp Definitions +Lamp Definitions Same goes for the lamps. They appear in the [Lamp Manager](xref:lamp_manager) and are used in the [lamp nodes](xref:uvs_node_reference#lamps) that VPE provides. @@ -53,7 +53,7 @@ It's worth noting that VPE currently doesn't provide any tools for creating ligh ### Events -Event Definitions +Event Definitions Unity provides [Custom Events](https://docs.unity3d.com/Packages/com.unity.visualscripting@1.7/manual/vs-events-reference.html#custom-events) which allow you to globally pass data across graphs. While this is a valid approach, VPE provides its own event nodes called *Pinball Events*, which allow you to declare your events. This has the benefit of being able to simply pick an event from a drop-down when configuring the nodes, as opposed to having to remember or separately document existing event names. diff --git a/VisualPinball.Unity/Documentation~/plugins/visual-scripting/variables.md b/VisualPinball.Unity/Documentation~/plugins/visual-scripting/variables.md index c2ee5423e..27a296d5d 100644 --- a/VisualPinball.Unity/Documentation~/plugins/visual-scripting/variables.md +++ b/VisualPinball.Unity/Documentation~/plugins/visual-scripting/variables.md @@ -32,7 +32,7 @@ If you're testing gameplay in the editor, the current values of both player and ### Setup -Variable Definitions +Variable Definitions In the hierarchy, select the GameObject where you added the visual scripting GLE (usually the root node of the table). In there, you'll find two sections, *Player Variables* and *Table Variables*. From 6e7c506f095bc73001fdad51b3177d6204842f18 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Oct 2023 18:41:30 +0200 Subject: [PATCH 132/159] doc: Fix search icon color on light. --- .../Documentation~/template/vpe/public/main.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css index bd1eaa6b9..bf6ae6f52 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -73,6 +73,10 @@ a { color: rgba(var(--bs-link-color-rgb), 0.6); } +[data-bs-theme=light] i.bi.bi-search { /* search icon color */ + color: white; +} + /* landing svg art colors */ svg .cls-1 { /* visual pinball engine */ fill: var(--bs-body-color); From 6db9981b7560fd752dd1d3abe5e4dca3114a8d44 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Oct 2023 22:59:51 +0200 Subject: [PATCH 133/159] runtime: Properly complain if no physics engine is available. --- .../VisualPinball.Unity/VPT/AnimationComponent.cs | 2 +- .../VPT/Bumper/BumperComponent.cs | 2 +- .../VPT/Flipper/FlipperComponent.cs | 2 +- .../VisualPinball.Unity/VPT/Gate/GateComponent.cs | 2 +- .../VPT/HitTarget/DropTargetComponent.cs | 2 +- .../VPT/HitTarget/HitTargetComponent.cs | 2 +- .../VisualPinball.Unity/VPT/ItemComponent.cs | 14 ++++++++++++++ .../VPT/Kicker/KickerComponent.cs | 2 +- .../VPT/MetalWireGuide/MetalWireGuideComponent.cs | 2 +- .../VPT/Plunger/PlungerComponent.cs | 2 +- .../VPT/Primitive/PrimitiveComponent.cs | 2 +- .../VisualPinball.Unity/VPT/Ramp/RampComponent.cs | 2 +- .../VPT/Rubber/RubberComponent.cs | 2 +- .../VPT/Spinner/SpinnerComponent.cs | 2 +- .../VPT/Surface/SurfaceComponent.cs | 2 +- .../VPT/Trigger/TriggerComponent.cs | 2 +- 16 files changed, 29 insertions(+), 15 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs index df485b9ca..950e0cddb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs @@ -29,7 +29,7 @@ public abstract class AnimationComponent : SubComponent().Register(this); + RegisterPhysics(); } private Entity MainEntity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs index 3eb309359..1ad472744 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs @@ -90,7 +90,7 @@ private void Awake() // register at player GetComponentInParent().RegisterBumper(this); if (GetComponentInChildren()) { - GetComponentInParent().Register(this); + RegisterPhysics(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index e95bb38a2..71a02498f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -480,7 +480,7 @@ private void Awake() { _originalRotateZ = _startAngle; GetComponentInParent().RegisterFlipper(this); - GetComponentInParent().Register(this); + RegisterPhysics(); } private void Start() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs index ebd482a11..401a6918a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs @@ -112,7 +112,7 @@ private void Awake() // register at player GetComponentInParent().RegisterGate(this); if (GetComponent()) { - GetComponentInParent().Register(this); + RegisterPhysics(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs index 65bc6a1c6..443033a30 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs @@ -135,7 +135,7 @@ private void Awake() // register at player GetComponentInParent().RegisterDropTarget(this); if (GetComponent() && GetComponentInChildren()) { - GetComponentInParent().Register(this); + RegisterPhysics(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs index bf5e7b2a2..f6c369d5e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs @@ -115,7 +115,7 @@ private void Awake() // register at player GetComponentInParent().RegisterHitTarget(this); if (GetComponent() && GetComponentInChildren()) { - GetComponentInParent().Register(this); + RegisterPhysics(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemComponent.cs index 557f09a90..205cc1538 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemComponent.cs @@ -16,7 +16,9 @@ // ReSharper disable InconsistentNaming +using NLog; using UnityEngine; +using Logger = NLog.Logger; namespace VisualPinball.Unity { @@ -27,6 +29,18 @@ public abstract class ItemComponent : MonoBehaviour { public abstract string ItemName { get; } + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + protected void RegisterPhysics() + { + var physicsEngine = GetComponentInParent(); + if (physicsEngine) { + physicsEngine.Register(this); + } else { + Logger.Error("No physics engine found in parent hierarchy."); + } + } + protected static void DrawArrow(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.025f, float arrowHeadAngle = 20.0f) { Debug.DrawRay(pos, direction); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs index c4d60df49..ea52202a8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs @@ -324,7 +324,7 @@ private void Awake() // register at player GetComponentInParent().RegisterKicker(this); if (GetComponent()) { - GetComponentInParent().Register(this); + RegisterPhysics(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs index 2082e2f83..27547784e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs @@ -94,7 +94,7 @@ private void Awake() { // register at player GetComponentInParent().RegisterMetalWireGuide(this); - GetComponentInParent().Register(this); + RegisterPhysics(); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs index f18149185..2296624ab 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs @@ -79,7 +79,7 @@ private void Awake() // register at player GetComponentInParent().RegisterPlunger(this, analogPlungerAction); if (GetComponent()) { - GetComponentInParent().Register(this); + RegisterPhysics(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs index 5cf613cb1..80248f59f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs @@ -247,7 +247,7 @@ private void Awake() { _originalRotateZ = ObjectRotation.z; GetComponentInParent().RegisterPrimitive(this); - GetComponentInParent().Register(this); + RegisterPhysics(); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs index f98039062..687980198 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs @@ -127,7 +127,7 @@ private void Awake() { // register at player GetComponentInParent().RegisterRamp(this); - GetComponentInParent().Register(this); + RegisterPhysics(); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs index 6fcc9f42e..bb718e0a2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs @@ -90,7 +90,7 @@ private void Awake() { // register at player GetComponentInParent().RegisterRubber(this); - GetComponentInParent().Register(this); + RegisterPhysics(); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs index af8c092f1..93092b28c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs @@ -96,7 +96,7 @@ private void Awake() { // register at player GetComponentInParent().RegisterSpinner(this); - GetComponentInParent().Register(this); + RegisterPhysics(); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs index 48ce7fe77..a15ce6d09 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs @@ -71,7 +71,7 @@ private void Awake() // register at player GetComponentInParent().RegisterSurface(this); if (GetComponentInChildren()) { - GetComponentInParent().Register(this); + RegisterPhysics(); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs index a7a186ea9..a99a80960 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs @@ -89,7 +89,7 @@ private void Awake() GetComponentInParent().RegisterTrigger(this); if (GetComponentInChildren()) { - GetComponentInParent().Register(this); + RegisterPhysics(); } } From b2115d74470a57eb4e28d2ac9194233ddbd9c8b5 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 22 Oct 2023 23:37:54 +0200 Subject: [PATCH 134/159] trough: Make ball prefab configurable. --- .../Inspectors/TroughInspector.cs | 7 +++++++ .../VisualPinball.Unity/VPT/Ball/BallManager.cs | 6 ++++-- .../VisualPinball.Unity/VPT/Kicker/KickerApi.cs | 4 ++-- .../VisualPinball.Unity/VPT/Trough/TroughApi.cs | 2 +- .../VisualPinball.Unity/VPT/Trough/TroughComponent.cs | 3 +++ 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/TroughInspector.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/TroughInspector.cs index cb13b132f..9677f45c7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/TroughInspector.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Inspectors/TroughInspector.cs @@ -47,6 +47,7 @@ public class TroughInspector : MainInspector private SerializedProperty _playfieldEntrySwitchProperty; private SerializedProperty _playfieldExitKickerProperty; private SerializedProperty _ballCountProperty; + private SerializedProperty _ballProperty; private SerializedProperty _switchCountProperty; private SerializedProperty _jamSwitchProperty; private SerializedProperty _rollTimeProperty; @@ -60,6 +61,7 @@ protected override void OnEnable() _typeProperty = serializedObject.FindProperty(nameof(TroughComponent.Type)); _playfieldEntrySwitchProperty = serializedObject.FindProperty(nameof(TroughComponent._playfieldEntrySwitch)); _playfieldExitKickerProperty = serializedObject.FindProperty(nameof(TroughComponent.PlayfieldExitKicker)); + _ballProperty = serializedObject.FindProperty(nameof(TroughComponent.Ball)); _ballCountProperty = serializedObject.FindProperty(nameof(TroughComponent.BallCount)); _switchCountProperty = serializedObject.FindProperty(nameof(TroughComponent.SwitchCount)); _jamSwitchProperty = serializedObject.FindProperty(nameof(TroughComponent.JamSwitch)); @@ -78,6 +80,11 @@ public override void OnInspectorGUI() DropDownProperty("Type", _typeProperty, TypeLabels, TypeValues); + PropertyField(_ballProperty, "Ball Prefab"); + if (MainComponent.Ball && !MainComponent.Ball.GetComponent()) { + EditorGUILayout.HelpBox("Ball prefab must contain a ball component.", MessageType.Error); + } + if (MainComponent.Type != TroughType.ClassicSingleBall) { PropertyField(_ballCountProperty); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index 33a25ca15..ee77df08a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -45,13 +45,15 @@ public void CreateBall(IBallCreationPosition ballCreator, float radius = 25f, fl CreateBall(ballCreator, radius, mass, 0); } - public void CreateBall(IBallCreationPosition ballCreator, float radius, float mass, int kickerId) + public void CreateBall(IBallCreationPosition ballCreator, float radius, float mass, int kickerId, GameObject ballPrefab = null) { var localPos = ballCreator.GetBallCreationPosition().ToUnityFloat3(); localPos.z += radius; var ballId = NumBallsCreated++; - var ballPrefab = RenderPipeline.Current.BallConverter.CreateDefaultBall(); + if (!ballPrefab) { + ballPrefab = RenderPipeline.Current.BallConverter.CreateDefaultBall(); + } var ballGo = Object.Instantiate(ballPrefab, _parent); var ballComp = ballGo.GetComponent(); ballGo.name = $"Ball {ballId}"; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs index 3a77221e3..458470868 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs @@ -70,9 +70,9 @@ void IApi.OnDestroy() { } - public void CreateBall() + public void CreateBall(GameObject ballPrefab = null) { - BallManager.CreateBall(MainComponent, 25f, 1f, ItemId); + BallManager.CreateBall(MainComponent, 25f, 1f, ItemId, ballPrefab); } public void CreateSizedBallWithMass(float radius, float mass) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs index 772478639..8309bf9bf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughApi.cs @@ -483,7 +483,7 @@ public bool EjectBall() return false; } Logger.Info("Trough: Spawning new ball."); - _ejectKicker.CreateBall(); + _ejectKicker.CreateBall(MainComponent.Ball); _ejectCoil.OnCoil(true); // open the switch of the ejected ball immediately diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughComponent.cs index 5df1c3520..dc78680bd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughComponent.cs @@ -61,6 +61,9 @@ public ITriggerComponent PlayfieldEntrySwitch public KickerComponent PlayfieldExitKicker; public string PlayfieldExitKickerItem = string.Empty; + [Tooltip("The prefab that will instantiated when ejecting a new ball.")] + public GameObject Ball; + [Range(1, 10)] [Tooltip("How many balls the trough holds when the game starts.")] public int BallCount = 6; From 27253fc0880c648c3abb449547f8c8a08f958767 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 23 Oct 2023 13:40:22 +0200 Subject: [PATCH 135/159] jobs: Fix playfield physmat and clean up more unused code. --- .../Game/PhysicsStaticCollision.cs | 8 +- .../Game/PhysicsStaticNarrowPhase.cs | 8 -- .../Physics/Collider/Collider.cs | 84 ------------------- .../Physics/Collider/ColliderReference.cs | 5 ++ .../Physics/Collider/Line3DCollider.cs | 7 +- .../Physics/Collider/LineCollider.cs | 2 +- .../Physics/Collider/LineZCollider.cs | 5 -- .../Physics/Collider/PointCollider.cs | 7 +- .../Physics/Collider/TriangleCollider.cs | 2 +- .../VPT/Playfield/PlayfieldApi.cs | 2 +- 10 files changed, 14 insertions(+), 116 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 5e27eedef..180f69517 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -59,22 +59,22 @@ private static void Collide(ref BallState ball, ref PhysicsState state) case ColliderType.Line: ref var lineCollider = ref state.Colliders.GetLineCollider(colliderId); - lineCollider.Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + lineCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Triangle: ref var triangleCollider = ref state.Colliders.GetTriangleCollider(colliderId); - triangleCollider.Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + triangleCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Line3D: ref var line3DCollider = ref state.Colliders.GetLine3DCollider(colliderId); - line3DCollider.Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + line3DCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Point: ref var pointCollider = ref state.Colliders.GetPointCollider(colliderId); - pointCollider.Collide(ref ball, ref state.EventQueue, ball.Id, in ball.CollisionEvent, ref state.Env.Random); + pointCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Bumper: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs index ffc28b026..246dd1f8b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticNarrowPhase.cs @@ -57,14 +57,6 @@ ref PhysicsState state PerfMarkerNarrowPhase.End(); } - private static float HitTest(ref BallState ball, in Collider collider, ref NativeList contacts) - { - ref var collEvent = ref ball.CollisionEvent; - var hitTime = Collider.HitTest(in collider, ref collEvent, in ball, ball.CollisionEvent.HitTime); - ball.CollisionEvent = collEvent; - return hitTime; - } - private static void SaveCollisions(ref BallState ball, ref CollisionEventData newCollEvent, ref NativeList contacts, int colliderId, float newTime) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 1ad3390e8..13d123b28 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -81,90 +81,6 @@ public unsafe ColliderBounds Bounds() { } } - internal static unsafe float HitTest(in Collider coll, ref CollisionEventData collEvent, in BallState ball, float dTime) - { - fixed (Collider* collider = &coll) - { - switch (collider->Type) - { - case ColliderType.Bumper: - // case ColliderType.Circle: - // return ((CircleCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); - // case ColliderType.Gate: - // return ((GateCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); - // case ColliderType.Line: - // return ((LineCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); - case ColliderType.LineZ: - return ((LineZCollider*) collider)->HitTest(ref collEvent, in ball, dTime); - case ColliderType.Line3D: - return ((Line3DCollider*) collider)->HitTest(ref collEvent, in ball, dTime); - case ColliderType.Point: - return ((PointCollider*) collider)->HitTest(ref collEvent, in ball, dTime); - case ColliderType.Plane: - return ((PlaneCollider*) collider)->HitTest(ref collEvent, in ball, dTime); - // case ColliderType.Spinner: - // return ((SpinnerCollider*) collider)->HitTest(ref collEvent, ref insideOf, in ball, dTime); - // case ColliderType.Triangle: - // return ((TriangleCollider*) collider)->HitTest(ref collEvent, in insideOf, in ball, dTime); - // case ColliderType.KickerCircle: - // case ColliderType.TriggerCircle: - // return ((CircleCollider*) collider)->HitTestBasicRadius(ref collEvent, ref insideOf, in ball, dTime, false, false, false); - // case ColliderType.TriggerLine: - // return ((LineCollider*) collider)->HitTestBasic(ref collEvent, ref insideOf, in ball, dTime, false, false, false); - - case ColliderType.Plunger: - throw new InvalidOperationException("ColliderType.Plunger must be hit-tested separately!"); - case ColliderType.Flipper: - throw new InvalidOperationException("ColliderType.Flipper must be hit-tested separately!"); - case ColliderType.LineSlingShot: - throw new InvalidOperationException("ColliderType.LineSlingShot must be hit-tested separately!"); - - default: - return -1; - } - } - } - - /// - /// Most colliders use the standard Collide3DWall routine, only overrides - /// are cast and dispatched to their respective implementation. - /// - internal static unsafe void Collide(in Collider coll, ref BallState ballState, - ref NativeQueue.ParallelWriter events, in int ballId, - in CollisionEventData collEvent, ref Random random) - { - fixed (Collider* collider = &coll) - { - switch (collider->Type) - { - case ColliderType.Circle: - ((CircleCollider*) collider)->Collide(ref ballState, in collEvent, ref random); - break; - case ColliderType.Line: - ((LineCollider*) collider)->Collide(ref ballState, ref events, in ballId, in collEvent, ref random); - break; - case ColliderType.Line3D: - ((Line3DCollider*) collider)->Collide(ref ballState, ref events, in ballId, in collEvent, ref random); - break; - case ColliderType.LineZ: - ((LineZCollider*) collider)->Collide(ref ballState, ref events, in ballId, in collEvent, ref random); - break; - case ColliderType.Plane: - ((PlaneCollider*) collider)->Collide(ref ballState, in collEvent, ref random); - break; - case ColliderType.Point: - ((PointCollider*) collider)->Collide(ref ballState, ref events, in ballId, in collEvent, ref random); - break; - case ColliderType.Triangle: - ((TriangleCollider*) collider)->Collide(ref ballState, ref events, in ballId, in collEvent, ref random); - break; - - default: - break; - } - } - } - internal static void FireHitEvent(ref BallState ball, ref NativeQueue.ParallelWriter events, in ColliderHeader collHeader) { if (collHeader.FireEvents/* && collHeader.IsEnabled*/) { // todo enabled diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs index ac133c56b..4f5c6c5fb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs @@ -68,6 +68,11 @@ public void Dispose() PlaneColliders.Dispose(); } + public int Count => CircleColliders.Length + FlipperColliders.Length + GateColliders.Length + + Line3DColliders.Length + LineSlingshotColliders.Length + LineColliders.Length + LineZColliders.Length + + PlungerColliders.Length + PointColliders.Length + SpinnerColliders.Length + TriangleColliders.Length + + PlaneColliders.Length; + internal List All { get { var list = new List(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs index bd6f37c77..ae89a629e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs @@ -107,11 +107,6 @@ public float HitTest(ref CollisionEventData collEvent, in BallState ball, float private static float HitTest(ref CollisionEventData collEvent, ref Line3DCollider coll, in BallState ball, float dTime) { - // todo - // if (!IsEnabled) { - // return -1.0f; - // } - var hitTestBall = ball; // transform ball to cylinder coordinate system @@ -132,7 +127,7 @@ private static float HitTest(ref CollisionEventData collEvent, ref Line3DCollide #endregion public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, - in int ballId, in CollisionEventData collEvent, ref Random random) + in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index 7ceadb240..e33dec540 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -228,7 +228,7 @@ public static float HitTestBasic(ref CollisionEventData collEvent, ref InsideOfs #region Collision public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, - in int ballId, in CollisionEventData collEvent, ref Random random) + in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs index 88861b2b6..5af4cdd6f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs @@ -72,11 +72,6 @@ public float HitTest(ref CollisionEventData collEvent, in BallState ball, float public static float HitTest(ref CollisionEventData collEvent, in LineZCollider coll, in BallState ball, float dTime) { - // todo - // if (!IsEnabled) { - // return -1.0f; - // } - var bp2d = new float2(ball.Position.x, ball.Position.y); var dist = bp2d - coll.XY; // relative ball position var dv = new float2(ball.Velocity.x, ball.Velocity.y); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs index 5c751d877..66020600a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs @@ -61,11 +61,6 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray.ParallelWriter hitEvents, - in int ballId, in CollisionEventData collEvent, ref Random random) + in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs index 7d1a6a350..a02870024 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs @@ -180,7 +180,7 @@ public float HitTest(ref CollisionEventData collEvent, in InsideOfs insideOfs, i #region Collision public void Collide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, - in int ballId, in CollisionEventData collEvent, ref Random random) + in CollisionEventData collEvent, ref Random random) { var dot = -math.dot(collEvent.HitNormal, ball.Velocity); BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in _normal, ref random); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs index 7684e480b..7067ab826 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs @@ -53,7 +53,7 @@ protected override void CreateColliders(ref ColliderReference colliders, float m if (meshComp && !meshComp.AutoGenerate) { var mf = GameObject.GetComponent(); if (mf && mf.sharedMesh) { - ColliderUtils.GenerateCollidersFromMesh(mf.sharedMesh.ToVpMesh().TransformToVpx(), info, ref colliders); + ColliderUtils.GenerateCollidersFromMesh(mf.sharedMesh.ToVpMesh().TransformToVpx(), planeColliderInfo, ref colliders); } else { Debug.LogWarning($"Could not find mesh filter on playfield {GameObject.name}"); From 42c800b9d4ec42ae78ff312181e08370724b06a6 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 23 Oct 2023 16:24:28 +0200 Subject: [PATCH 136/159] physics: Fix playfield material. --- .../VisualPinball.Unity/VPT/CollidableApi.cs | 1 - .../VisualPinball.Unity/VPT/IApi.cs | 5 --- .../VPT/Playfield/PlayfieldApi.cs | 34 +++---------------- .../Playfield/PlayfieldColliderComponent.cs | 2 +- 4 files changed, 6 insertions(+), 36 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs index cbeb1c7a2..6f6ec848c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollidableApi.cs @@ -37,7 +37,6 @@ protected CollidableApi(GameObject go, Player player, PhysicsEngine physicsEngin #region Collider bool IApiColliderGenerator.IsColliderAvailable => ColliderComponent; - bool IApiColliderGenerator.IsColliderEnabled => ColliderComponent && ColliderComponent.isActiveAndEnabled; protected virtual bool FireHitEvents => false; protected virtual float HitThreshold => 0; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs index 6a4a9e5db..74f3816ad 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/IApi.cs @@ -50,11 +50,6 @@ public interface IApiColliderGenerator /// ColliderInfo GetColliderInfo(); - /// - /// If false, this will be included in the quad tree but marked as inactive. - /// - bool IsColliderEnabled { get; } - /// /// If false, this won't be included in the quad tree. /// diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs index 7067ab826..79121ef15 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldApi.cs @@ -14,10 +14,8 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System.Collections.Generic; using Unity.Mathematics; using UnityEngine; -using VisualPinball.Engine.VPT; using VisualPinball.Engine.VPT.Table; using VisualPinball.Unity.Playfield; @@ -34,36 +32,23 @@ internal PlayfieldApi(GameObject go, Player player, PhysicsEngine physicsEngine) protected override void CreateColliders(ref ColliderReference colliders, float margin) { var info = ((IApiColliderGenerator)this).GetColliderInfo(); - var planeColliderInfo = new ColliderInfo { - Id = -1, // is set during allocation - ItemId = ItemId, - ItemType = ItemType.Table, - FireEvents = false, - Material = new PhysicsMaterialData { - Elasticity = ColliderComponent.Elasticity, - ElasticityFalloff = ColliderComponent.ElasticityFalloff, - Friction = ColliderComponent.Friction, - ScatterAngleRad = ColliderComponent.Scatter - }, - HitThreshold = 0 - }; // do we have a playfield mesh? var meshComp = GameObject.GetComponent(); if (meshComp && !meshComp.AutoGenerate) { var mf = GameObject.GetComponent(); if (mf && mf.sharedMesh) { - ColliderUtils.GenerateCollidersFromMesh(mf.sharedMesh.ToVpMesh().TransformToVpx(), planeColliderInfo, ref colliders); - + ColliderUtils.GenerateCollidersFromMesh(mf.sharedMesh.ToVpMesh().TransformToVpx(), info, ref colliders); + } else { Debug.LogWarning($"Could not find mesh filter on playfield {GameObject.name}"); - colliders.Add(new PlaneCollider(new float3(0, 0, 1), MainComponent.TableHeight, planeColliderInfo)); + colliders.Add(new PlaneCollider(new float3(0, 0, 1), MainComponent.TableHeight, info)); } } else { - colliders.Add(new PlaneCollider(new float3(0, 0, 1), MainComponent.TableHeight, planeColliderInfo)); + colliders.Add(new PlaneCollider(new float3(0, 0, 1), MainComponent.TableHeight, info)); } // add playfield glass collider - colliders.Add(new PlaneCollider(new float3(0, 0, -1), MainComponent.GlassHeight, planeColliderInfo)); + colliders.Add(new PlaneCollider(new float3(0, 0, -1), MainComponent.GlassHeight, info)); if (ColliderComponent.CollideWithBounds) { @@ -100,15 +85,6 @@ protected override void CreateColliders(ref ColliderReference colliders, float m info )); } - - // glass (it's handled by the plane) - // var rgv3D = new[] { - // new float3(MainComponent.Left, MainComponent.Top, MainComponent.GlassHeight), - // new float3(MainComponent.Right, MainComponent.Top, MainComponent.GlassHeight), - // new float3(MainComponent.Right, MainComponent.Bottom, MainComponent.GlassHeight), - // new float3(MainComponent.Left, MainComponent.Bottom, MainComponent.GlassHeight) - // }; - // ColliderUtils.Generate3DPolyColliders(rgv3D, info, colliders); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs index ff302d14a..4ebc4d8b3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs @@ -53,7 +53,7 @@ public class PlayfieldColliderComponent : ColliderComponent GetPhysicsMaterialData(0, 0); + public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) => new PlayfieldApi(gameObject, player, physicsEngine); } From 9bcdd93194a04b841b8cd606bf490f226a194531 Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 23 Oct 2023 18:20:07 +0200 Subject: [PATCH 137/159] perf: Make lamps fade without GC. --- .../Game/Engines/GamelogicEngineLamp.cs | 13 +-- .../Managers/Lamp/LampListViewItemRenderer.cs | 4 +- .../VisualPinball.Unity/Game/LampPlayer.cs | 79 +++++++++++++++---- .../VPT/Light/LightComponent.cs | 46 ++++++++--- 4 files changed, 112 insertions(+), 30 deletions(-) diff --git a/VisualPinball.Engine/Game/Engines/GamelogicEngineLamp.cs b/VisualPinball.Engine/Game/Engines/GamelogicEngineLamp.cs index a0225441a..04697dc76 100644 --- a/VisualPinball.Engine/Game/Engines/GamelogicEngineLamp.cs +++ b/VisualPinball.Engine/Game/Engines/GamelogicEngineLamp.cs @@ -78,12 +78,12 @@ public class GamelogicEngineLamp : IGamelogicEngineDeviceItem public GamelogicEngineLamp(string id) { - Id = id; + _id = id; } public GamelogicEngineLamp(int id) { - Id = id.ToString(); + _id = id.ToString(); } } @@ -108,7 +108,7 @@ public enum LampStatus Blinking = 2, } - public class LampState + public struct LampState { public LampStatus Status { get => _status; @@ -133,11 +133,12 @@ public float Intensity { public Color Color; private LampStatus _status; - private LampStatus _lastOnStatus = LampStatus.On; + private LampStatus _lastOnStatus; public LampState(LampStatus status, Color color) { - Status = status; + _lastOnStatus = status != LampStatus.Off ? status : LampStatus.On; + _status = status; Color = color; } @@ -151,12 +152,14 @@ public LampState(float intensity) _status = LampStatus.On; Color = new Color(255, 255, 255, (int)(intensity * 255)); } + _lastOnStatus = LampStatus.On; } public LampState(Color color) { _status = color.A > 0 ? LampStatus.On : LampStatus.Off; Color = color; + _lastOnStatus = LampStatus.On; } public void SetChannel(ColorChannel channel, float value) diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Managers/Lamp/LampListViewItemRenderer.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Managers/Lamp/LampListViewItemRenderer.cs index 29cb31b4b..c5e1a0297 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Managers/Lamp/LampListViewItemRenderer.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Managers/Lamp/LampListViewItemRenderer.cs @@ -101,7 +101,9 @@ protected override void OnIconClick(LampListData data, bool pressedDown) var lamp = player.Lamp(data.Device); lamp?.OnChange(pressedDown); if (player.LampStatuses.ContainsKey(data.Id)) { - player.LampStatuses[data.Id].IsOn = pressedDown; + var status = player.LampStatuses[data.Id]; + status.IsOn = pressedDown; + player.LampStatuses[data.Id] = status; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/LampPlayer.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/LampPlayer.cs index 0d909bef6..34fa7aca5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/LampPlayer.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/LampPlayer.cs @@ -98,38 +98,57 @@ public void OnStart() private void HandleLampsEvent(object sender, LampsEventArgs lampsEvent) { + LampAction action = default; foreach (var lampEvent in lampsEvent.LampsChanged) { - Apply(lampEvent.Id, lampEvent.Source, lampEvent.IsCoil, (state, lamp, mapping) => ApplyValue(lampEvent.Id, lampEvent.Value, state, lamp, mapping)); + if (Apply(lampEvent.Id, lampEvent.Source, lampEvent.IsCoil, ref action)) { + ApplyValue(lampEvent.Id, lampEvent.Value, action.State, action.Lamp, action.Mapping); + } } } private void HandleLampEvent(object sender, LampEventArgs lampEvent) { - Apply(lampEvent.Id, lampEvent.Source, lampEvent.IsCoil, (state, lamp, mapping) => ApplyValue(lampEvent.Id, lampEvent.Value, state, lamp, mapping)); + LampAction action = default; + if (Apply(lampEvent.Id, lampEvent.Source, lampEvent.IsCoil, ref action)) { + ApplyValue(lampEvent.Id, lampEvent.Value, action.State, action.Lamp, action.Mapping); + } } public void HandleLampEvent(string id, float value) { - Apply(id, LampSource.Lamp, false, (state, lamp, mapping) => ApplyValue(id, value, state, lamp, mapping)); + LampAction action = default; + if (Apply(id, LampSource.Lamp, false, ref action)) { + ApplyValue(id, value, action.State, action.Lamp, action.Mapping); + } } public void HandleLampEvent(string id, LampStatus status) { - Apply(id, LampSource.Lamp, false, (state, lamp, _) => ApplyStatus(id, status, state, lamp)); + LampAction action = default; + if (Apply(id, LampSource.Lamp, false, ref action)) { + ApplyStatus(id, status, action.State, action.Lamp); + } } public void HandleLampEvent(string id, Color color) { - Apply(id, LampSource.Lamp, false, (state, lamp, _) => ApplyColor(id, color, state, lamp)); + LampAction action = default; + if (Apply(id, LampSource.Lamp, false, ref action)) { + ApplyColor(id, color, action.State, action.Lamp); + } } public void HandleCoilEvent(string id, bool isEnabled) { - Apply(id, LampSource.Lamp, true, (state, lamp, _) => ApplyStatus(id, isEnabled ? LampStatus.On : LampStatus.Off, state, lamp)); + LampAction action = default; + if (Apply(id, LampSource.Lamp, true, ref action)) { + ApplyStatus(id, isEnabled ? LampStatus.On : LampStatus.Off, action.State, action.Lamp); + } } - private void Apply(string id, LampSource lampSource, bool isCoil, Action action) + private bool Apply(string id, LampSource lampSource, bool isCoil, ref LampAction action) { + var hasChanged = false; if (_lampAssignments.ContainsKey(id)) { foreach (var component in _lampAssignments[id]) { var mapping = _lampMappings[id][component]; @@ -141,20 +160,21 @@ private void Apply(string id, LampSource lampSource, bool isCoil, Action + /// The current light intensity, between 0 and 1. + /// private float _value; + private float _newValue; + private float _oldValue; + private float _newValueAt; + private float _oldValueAt; + private Color _color; private bool _hasLights; private readonly List<(Light, float)> _lights = new(); @@ -165,9 +173,8 @@ public override void UpdateTransforms() public bool Enabled { set { - StopAllCoroutines(); - SetLightIntensity(value ? 1 : 0); - SetMaterialIntensity(value ? 1 : 0); + SetLightIntensity(value ? _value : 0); + SetMaterialIntensity(value ? _value : 0); } } @@ -224,16 +231,37 @@ private void Awake() _hasLights = _lights.Count > 0 || _materials.Count > 0; } + private void Update() + { + if (_value == _newValue) { + return; + } + var durationSeconds = _newValueAt - _oldValueAt; + var position = durationSeconds == 0 + ? 1 + : (Time.fixedTime - _oldValueAt) / durationSeconds; + _value = position >= 1 // done? + ? _newValue + : math.lerp(_oldValue, _newValue, position); + SetLightIntensity(_value); + SetMaterialIntensity(_value); + } + public void FadeTo(float value) { if (!_hasLights) { return; } if (FadeEnabled) { - StopAllCoroutines(); - StartCoroutine(nameof(Fade), value); + _oldValue = _value; + _oldValueAt = Time.fixedTime; + _newValue = value; + _newValueAt = Time.fixedTime + (_value < value + ? FadeSpeedUp * (1 - _value) + : FadeSpeedDown * _value); } else { + _newValue = value; _value = value; SetLightIntensity(value); SetMaterialIntensity(value); @@ -273,19 +301,19 @@ private IEnumerator Blink(float blinkIntensity) private IEnumerator Fade(float value) { var counter = 0f; - var duration = _value < value + var durationSeconds = _value < value ? FadeSpeedUp * (1 - _value) : FadeSpeedDown * _value; - if (duration == 0) { + if (durationSeconds == 0) { _value = value; SetLightIntensity(value); SetMaterialIntensity(value); } else { - while (counter <= duration) { + while (counter <= durationSeconds) { counter += Time.deltaTime; - var position = counter / duration; + var position = counter / durationSeconds; var newValue = Mathf.Lerp(_value, value, position); yield return SetIntensity(newValue); } From e40d21a87b83acc6d9ba23026ba2f36deef431a0 Mon Sep 17 00:00:00 2001 From: jsm174 Date: Tue, 24 Oct 2023 16:43:39 -0400 Subject: [PATCH 138/159] ci: remove unity version from unity-test-runner --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2d8e154e0..689405da8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,7 +65,7 @@ jobs: - uses: game-ci/unity-test-runner@main id: test with: - unityVersion: "2022.3.10f1" + #unityVersion: "2022.3.10f1" projectPath: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~ artifactsPath: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/artifacts testMode: all From 3772961a226541309fb062000991b8b4cd85a538 Mon Sep 17 00:00:00 2001 From: jsm174 Date: Tue, 24 Oct 2023 16:58:30 -0400 Subject: [PATCH 139/159] ci: remove cache and bump setup-dotnet --- .github/workflows/build.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 689405da8..a075abe11 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,7 +30,7 @@ jobs: rid: android-arm64-v8a steps: - uses: actions/checkout@v3 - - uses: actions/setup-dotnet@v1 + - uses: actions/setup-dotnet@v3 with: dotnet-version: '3.1.x' - name: Build @@ -55,13 +55,13 @@ jobs: with: name: Plugins path: VisualPinball.Unity/Plugins - - uses: actions/cache@v3 - with: - path: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Library - key: Library-Test-Project - restore-keys: | - Library-Test-Project - Library + #- uses: actions/cache@v3 + # with: + # path: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Library + # key: Library-Test-Project + # restore-keys: | + # Library-Test-Project + # Library - uses: game-ci/unity-test-runner@main id: test with: From 9c2d4d3e0f7127e7c2450a8544c966e01af60810 Mon Sep 17 00:00:00 2001 From: freezy Date: Tue, 24 Oct 2023 14:10:32 +0200 Subject: [PATCH 140/159] jobs: Don't copy colliders when creating quadtree. --- .../Physics/Collider/ColliderReference.cs | 154 ++++++++++++++---- .../VPT/ColliderComponent.cs | 5 +- 2 files changed, 121 insertions(+), 38 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs index 4f5c6c5fb..dbcd10492 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs @@ -15,9 +15,8 @@ // along with this program. If not, see . using System; -using System.Collections.Generic; -using System.Linq; using Unity.Collections; +using VisualPinball.Unity.Collections; namespace VisualPinball.Unity { @@ -36,6 +35,9 @@ public struct ColliderReference : IDisposable internal NativeList TriangleColliders; internal NativeList PlaneColliders; + private NativeHashMap _lookup; + private int _currentIndex; + public ColliderReference(Allocator allocator) { CircleColliders = new NativeList(allocator); @@ -50,6 +52,8 @@ public ColliderReference(Allocator allocator) SpinnerColliders = new NativeList(allocator); TriangleColliders = new NativeList(allocator); PlaneColliders = new NativeList(allocator); + _currentIndex = 0; + _lookup = new NativeHashMap(8192, allocator); } public void Dispose() @@ -68,41 +72,121 @@ public void Dispose() PlaneColliders.Dispose(); } - public int Count => CircleColliders.Length + FlipperColliders.Length + GateColliders.Length - + Line3DColliders.Length + LineSlingshotColliders.Length + LineColliders.Length + LineZColliders.Length - + PlungerColliders.Length + PointColliders.Length + SpinnerColliders.Length + TriangleColliders.Length - + PlaneColliders.Length; - - internal List All { - get { - var list = new List(); - list.AddRange(CircleColliders.Select(c => (ICollider)c)); - list.AddRange(FlipperColliders.Select(c => (ICollider)c)); - list.AddRange(GateColliders.Select(c => (ICollider)c)); - list.AddRange(Line3DColliders.Select(c => (ICollider)c)); - list.AddRange(LineSlingshotColliders.Select(c => (ICollider)c)); - list.AddRange(LineColliders.Select(c => (ICollider)c)); - list.AddRange(LineZColliders.Select(c => (ICollider)c)); - list.AddRange(PlungerColliders.Select(c => (ICollider)c)); - list.AddRange(PointColliders.Select(c => (ICollider)c)); - list.AddRange(SpinnerColliders.Select(c => (ICollider)c)); - list.AddRange(TriangleColliders.Select(c => (ICollider)c)); - list.AddRange(PlaneColliders.Select(c => (ICollider)c)); - return list; + public int Count => _lookup.Count; + + public ICollider this[int i] => LookupCollider(i); + + private ICollider LookupCollider(int i) + { + if (_lookup.ContainsKey(i)) { + throw new IndexOutOfRangeException($"Invalid index {i} when looking up collider."); + } + + var lookup = _lookup[i]; + switch (lookup.Type) { + case ColliderType.Circle: return CircleColliders.GetElementAsRef(lookup.Index); + case ColliderType.Flipper: return FlipperColliders.GetElementAsRef(lookup.Index); + case ColliderType.Gate: return GateColliders.GetElementAsRef(lookup.Index); + case ColliderType.Line3D: return Line3DColliders.GetElementAsRef(lookup.Index); + case ColliderType.LineSlingShot: return LineSlingshotColliders.GetElementAsRef(lookup.Index); + case ColliderType.Line: return LineColliders.GetElementAsRef(lookup.Index); + case ColliderType.LineZ: return LineZColliders.GetElementAsRef(lookup.Index); + case ColliderType.Plunger: return PlungerColliders.GetElementAsRef(lookup.Index); + case ColliderType.Point: return PointColliders.GetElementAsRef(lookup.Index); + case ColliderType.Spinner: return SpinnerColliders.GetElementAsRef(lookup.Index); + case ColliderType.Triangle: return TriangleColliders.GetElementAsRef(lookup.Index); + case ColliderType.Plane: return PlaneColliders.GetElementAsRef(lookup.Index); + } + throw new ArgumentException($"Unknown lookup type."); + } + + #region Add + + internal void Add(CircleCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.Circle, CircleColliders.Length); + CircleColliders.Add(collider); + } + + internal void Add(FlipperCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.Flipper, FlipperColliders.Length); + FlipperColliders.Add(collider); + } + + internal void Add(GateCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.Gate, GateColliders.Length); + GateColliders.Add(collider); + } + + internal void Add(Line3DCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.Line3D, Line3DColliders.Length); + Line3DColliders.Add(collider); + } + + internal void Add(LineSlingshotCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.LineSlingShot, LineSlingshotColliders.Length); + LineSlingshotColliders.Add(collider); + } + + internal void Add(LineCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.Line, LineColliders.Length); + LineColliders.Add(collider); + } + + internal void Add(LineZCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.LineZ, LineZColliders.Length); + LineZColliders.Add(collider); + } + + internal void Add(PlungerCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.Plunger, PlungerColliders.Length); + PlungerColliders.Add(collider); + } + + internal void Add(PointCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.Point, PointColliders.Length); + PointColliders.Add(collider); + } + + internal void Add(SpinnerCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.Spinner, SpinnerColliders.Length); + SpinnerColliders.Add(collider); + } + + internal void Add(TriangleCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.Triangle, TriangleColliders.Length); + TriangleColliders.Add(collider); + } + + internal void Add(PlaneCollider collider) + { + _lookup[_currentIndex++] = new Lookup(ColliderType.Plane, PlaneColliders.Length); + PlaneColliders.Add(collider); + } + + #endregion + + private readonly struct Lookup + { + public readonly ColliderType Type; + public readonly int Index; + + public Lookup(ColliderType type, int index) + { + Type = type; + Index = index; } } - internal void Add(CircleCollider collider) => CircleColliders.Add(collider); - internal void Add(FlipperCollider collider) => FlipperColliders.Add(collider); - internal void Add(GateCollider collider) => GateColliders.Add(collider); - internal void Add(Line3DCollider collider) => Line3DColliders.Add(collider); - internal void Add(LineSlingshotCollider collider) => LineSlingshotColliders.Add(collider); - internal void Add(LineCollider collider) => LineColliders.Add(collider); - internal void Add(LineZCollider collider) => LineZColliders.Add(collider); - internal void Add(PlungerCollider collider) => PlungerColliders.Add(collider); - internal void Add(PointCollider collider) => PointColliders.Add(collider); - internal void Add(SpinnerCollider collider) => SpinnerColliders.Add(collider); - internal void Add(TriangleCollider collider) => TriangleColliders.Add(collider); - internal void Add(PlaneCollider collider) => PlaneColliders.Add(collider); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index cb571ce7b..050920697 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -146,9 +146,8 @@ private void OnDrawGizmos() } if (ShowAabbs) { - var colliderList = colliders.All; - for (var i = 0; i < colliderList.Count; i++) { - var col = colliderList[i]; + for (var i = 0; i < colliders.Count; i++) { + var col = colliders[i]; DrawAabb(col.Bounds.Aabb, i == SelectedCollider); } } From c63c920d8de885befd77145ed44149d131b520f6 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 25 Oct 2023 21:52:32 +0200 Subject: [PATCH 141/159] jobs: Pass collision header instead of collider. --- .../VisualPinball.Unity/Game/PhysicsState.cs | 6 ++-- .../Game/PhysicsStaticCollision.cs | 32 +++++++++---------- .../Physics/Collider/CircleCollider.cs | 22 ++++++------- .../Physics/Collider/Collider.cs | 4 +-- .../Physics/Collider/Line3DCollider.cs | 18 +++++------ .../Physics/Collider/LineCollider.cs | 24 +++++++------- .../Physics/Collider/LineSlingshotCollider.cs | 18 +++++------ .../Physics/Collider/LineZCollider.cs | 18 +++++------ .../Physics/Collider/PlaneCollider.cs | 20 ++++++------ .../Physics/Collider/PointCollider.cs | 18 +++++------ .../Physics/Collider/TriangleCollider.cs | 22 ++++++------- .../Physics/Collision/ContactPhysics.cs | 6 ++-- .../VPT/Bumper/BumperCollider.cs | 6 ++-- .../VPT/Flipper/FlipperCollider.cs | 22 ++++++------- .../VPT/Gate/GateCollider.cs | 14 ++++---- .../VPT/HitTarget/TargetCollider.cs | 16 +++++----- .../VPT/Plunger/PlungerCollider.cs | 12 +++---- .../VPT/Spinner/SpinnerCollider.cs | 10 +++--- .../VPT/Trigger/TriggerCollider.cs | 12 +++---- 19 files changed, 150 insertions(+), 150 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 3b832d353..daa7daf1d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -72,12 +72,12 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs SwapBallCollisionHandling = swapBallCollisionHandling; } - internal Collider GetCollider(int colliderId) => Colliders.Value.Colliders[colliderId].Value; + internal ColliderHeader GetColliderHeader(int colliderId) => Colliders.Value.Colliders[colliderId].Value.Header; internal bool IsColliderActive(int colliderId) { - var collider = GetCollider(colliderId); - return !DisabledCollisionItems.Contains(collider.ItemId); + var collHeader = GetColliderHeader(colliderId); + return !DisabledCollisionItems.Contains(collHeader.ItemId); } #region States diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 180f69517..ba57c28b7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -40,8 +40,8 @@ internal static void Collide(float hitTime, ref BallState ball, ref PhysicsState private static void Collide(ref BallState ball, ref PhysicsState state) { var colliderId = ball.CollisionEvent.ColliderId; - var collider = state.GetCollider(colliderId); - if (CollidesWithItem(ref collider, ref ball, ref state)) { + var collHeader = state.GetColliderHeader(colliderId); + if (CollidesWithItem(ref collHeader, ref ball, ref state)) { return; } @@ -80,7 +80,7 @@ private static void Collide(ref BallState ball, ref PhysicsState state) case ColliderType.Bumper: ref var bumperState = ref state.GetBumperState(colliderId); BumperCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref bumperState.RingAnimation, ref bumperState.SkirtAnimation, - in collider, in bumperState.Static, ref state.Env.Random); + in collHeader, in bumperState.Static, ref state.Env.Random); break; case ColliderType.Flipper: @@ -95,7 +95,7 @@ private static void Collide(ref BallState ball, ref PhysicsState state) case ColliderType.Gate: ref var gateState = ref state.GetGateState(colliderId); GateCollider.Collide(ref ball, ref ball.CollisionEvent, ref gateState.Movement, ref state.EventQueue, - in collider, in gateState.Static); + in collHeader, in gateState.Static); break; case ColliderType.LineSlingShot: @@ -117,52 +117,52 @@ private static void Collide(ref BallState ball, ref PhysicsState state) case ColliderType.TriggerCircle: case ColliderType.TriggerLine: - TriggerCollide(ref ball, ref state, in collider); + TriggerCollide(ref ball, ref state, in collHeader); break; case ColliderType.KickerCircle: ref var kickerState = ref state.GetKickerState(colliderId); KickerCollider.Collide(ref ball, ref state.EventQueue, ref state.InsideOfs, ref kickerState.Collision, - in kickerState.Static, in kickerState.CollisionMesh, in ball.CollisionEvent, collider.ItemId); + in kickerState.Static, in kickerState.CollisionMesh, in ball.CollisionEvent, collHeader.ItemId); break; } } - private static bool CollidesWithItem(ref Collider collider, ref BallState ball, ref PhysicsState state) + private static bool CollidesWithItem(ref ColliderHeader collHeader, ref BallState ball, ref PhysicsState state) { // hit target var colliderId = ball.CollisionEvent.ColliderId; - if (collider.Header.ItemType == ItemType.HitTarget) { + if (collHeader.ItemType == ItemType.HitTarget) { - var normal = collider.Type == ColliderType.Triangle + var normal = collHeader.Type == ColliderType.Triangle ? state.Colliders.GetTriangleCollider(colliderId).Normal() : ball.CollisionEvent.HitNormal; if (state.HasDropTargetState(colliderId)) { ref var dropTargetState = ref state.GetDropTargetState(colliderId); - TargetCollider.DropTargetCollide(ref ball, ref state.EventQueue, ref dropTargetState.Animation, in normal, in ball.CollisionEvent, in collider, ref state.Env.Random); + TargetCollider.DropTargetCollide(ref ball, ref state.EventQueue, ref dropTargetState.Animation, in normal, in ball.CollisionEvent, in collHeader, ref state.Env.Random); return true; } if (state.HasHitTargetState(colliderId)) { ref var hitTargetState = ref state.GetHitTargetState(colliderId); - TargetCollider.HitTargetCollide(ref ball, ref state.EventQueue, ref hitTargetState.Animation, in normal, in ball.CollisionEvent, in collider, ref state.Env.Random); + TargetCollider.HitTargetCollide(ref ball, ref state.EventQueue, ref hitTargetState.Animation, in normal, in ball.CollisionEvent, in collHeader, ref state.Env.Random); return true; } // trigger - } else if (collider.Header.ItemType == ItemType.Trigger) { - TriggerCollide(ref ball, ref state, in collider); + } else if (collHeader.ItemType == ItemType.Trigger) { + TriggerCollide(ref ball, ref state, in collHeader); return true; } return false; } - private static void TriggerCollide(ref BallState ball, ref PhysicsState state, in Collider collider) + private static void TriggerCollide(ref BallState ball, ref PhysicsState state, in ColliderHeader collHeader) { - ref var triggerState = ref state.GetTriggerState(collider.Id); - TriggerCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref state.InsideOfs, ref triggerState.Animation, in collider); + ref var triggerState = ref state.GetTriggerState(collHeader.Id); + TriggerCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref state.InsideOfs, ref triggerState.Animation, in collHeader); if (triggerState.FlipperCorrection.IsEnabled) { if (triggerState.Animation.UnHitEvent) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs index d8bd385cb..42394c455 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs @@ -24,9 +24,9 @@ namespace VisualPinball.Unity { internal struct CircleCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; public readonly float2 Center; public readonly float Radius; @@ -34,7 +34,7 @@ internal struct CircleCollider : ICollider private readonly float _zHigh; private readonly float _zLow; - public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( + public ColliderBounds Bounds => new ColliderBounds(Header.ItemId, Header.Id, new Aabb( Center.x - Radius, Center.x + Radius, Center.y - Radius, @@ -45,7 +45,7 @@ internal struct CircleCollider : ICollider public CircleCollider(float2 center, float radius, float zLow, float zHigh, ColliderInfo info, ColliderType type = ColliderType.Circle) : this() { - _header.Init(info, type); + Header.Init(info, type); Center = center; Radius = radius; _zHigh = zHigh; @@ -54,7 +54,7 @@ public CircleCollider(float2 center, float radius, float zLow, float zHigh, Coll public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; + Header.Id = colliderId; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[colliderId]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( @@ -84,8 +84,8 @@ public float HitTestBasicRadius(ref CollisionEventData collEvent, ref InsideOfs var dv = ball.Velocity; var capsule3D = !lateral && ball.Position.z > _zHigh; - var isKicker = _header.ItemType == ItemType.Kicker; - var isKickerOrTrigger = _header.ItemType == ItemType.Trigger || _header.ItemType == ItemType.Kicker; + var isKicker = Header.ItemType == ItemType.Kicker; + var isKickerOrTrigger = Header.ItemType == ItemType.Trigger || Header.ItemType == ItemType.Kicker; float targetRadius; if (capsule3D) { @@ -128,7 +128,7 @@ public float HitTestBasicRadius(ref CollisionEventData collEvent, ref InsideOfs // Kicker is special.. handle ball stalled on kicker, commonly hit while receding, knocking back into kicker pocket if (isKicker && bnd <= 0 && bnd >= -Radius && a < PhysicsConstants.ContactVel * PhysicsConstants.ContactVel/* && ball.Hit.IsRealBall()*/) { - insideOfs.SetOutsideOf(_header.ItemId, ball.Id); + insideOfs.SetOutsideOf(Header.ItemId, ball.Id); } // contact positive possible in future ... objects Negative in contact now @@ -148,13 +148,13 @@ public float HitTestBasicRadius(ref CollisionEventData collEvent, ref InsideOfs hitTime = math.max(0.0f, (float) (-bnd / bnv)); } - } else if (isKickerOrTrigger /*&& ball.Hit.IsRealBall()*/ && bnd < 0 == insideOfs.IsOutsideOf(_header.ItemId, ball.Id)) { + } else if (isKickerOrTrigger /*&& ball.Hit.IsRealBall()*/ && bnd < 0 == insideOfs.IsOutsideOf(Header.ItemId, ball.Id)) { // triggers & kickers // here if ... ball inside and no hit set .... or ... ball outside and hit set if (math.abs(bnd - Radius) < 0.05) { // if ball appears in center of trigger, then assumed it was gen"ed there - insideOfs.SetInsideOf(_header.ItemId, ball.Id); // special case for trigger overlaying a kicker + insideOfs.SetInsideOf(Header.ItemId, ball.Id); // special case for trigger overlaying a kicker } else { // this will add the ball to the trigger space without a Hit @@ -229,7 +229,7 @@ public float HitTestBasicRadius(ref CollisionEventData collEvent, ref InsideOfs public void Collide(ref BallState ball, in CollisionEventData collEvent, ref Random random) { - BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); + BallCollider.Collide3DWall(ref ball, in Header.Material, in collEvent, in collEvent.HitNormal, ref random); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 13d123b28..587ba3a23 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -102,9 +102,9 @@ internal static void FireHitEvent(ref BallState ball, ref NativeQueue } } - internal static void Contact(ref Collider coll, ref BallState ball, in CollisionEventData collEvent, double hitTime, in float3 gravity) + internal static void Contact(in ColliderHeader collHeader, ref BallState ball, in CollisionEventData collEvent, double hitTime, in float3 gravity) { - BallCollider.HandleStaticContact(ref ball, in collEvent, coll.Header.Material.Friction, (float)hitTime, gravity); + BallCollider.HandleStaticContact(ref ball, in collEvent, collHeader.Material.Friction, (float)hitTime, gravity); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs index ae89a629e..0f7b3ee54 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs @@ -23,9 +23,9 @@ namespace VisualPinball.Unity { internal struct Line3DCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; // these are all used when casting this to LineZCollider, // so the order is important too. @@ -41,7 +41,7 @@ internal struct Line3DCollider : ICollider public Line3DCollider(float3 v1, float3 v2, ColliderInfo info) : this() { - _header.Init(info, ColliderType.Line3D); + Header.Init(info, ColliderType.Line3D); var vLine = math.normalize(v2 - v1); @@ -73,7 +73,7 @@ public Line3DCollider(float3 v1, float3 v2, ColliderInfo info) : this() _zLow = math.min(trans1.z, trans2Z); _zHigh = math.max(trans1.z, trans2Z); - Bounds = new ColliderBounds(_header.ItemId, _header.Id, new Aabb( + Bounds = new ColliderBounds(Header.ItemId, Header.Id, new Aabb( math.min(v1.x, v2.x), math.max(v1.x, v2.x), math.min(v1.y, v2.y), @@ -85,11 +85,11 @@ public Line3DCollider(float3 v1, float3 v2, ColliderInfo info) : this() public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; + Header.Id = colliderId; var bounds = Bounds; bounds.ColliderId = colliderId; Bounds = bounds; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[_header.Id]); + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), @@ -130,11 +130,11 @@ public void Collide(ref BallState ball, ref NativeQueue.ParallelWrite in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); - BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); + BallCollider.Collide3DWall(ref ball, in Header.Material, in collEvent, in collEvent.HitNormal, ref random); - if (_header.FireEvents && dot >= _header.Threshold && _header.IsPrimitive) { + if (Header.FireEvents && dot >= Header.Threshold && Header.IsPrimitive) { // todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in Header); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index e33dec540..129219577 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -25,9 +25,9 @@ namespace VisualPinball.Unity { internal struct LineCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; public float2 V1; public float2 V2; @@ -37,15 +37,15 @@ internal struct LineCollider : ICollider public readonly float ZHigh; private float _length; - internal ItemType ItemType => _header.ItemType; - private int ItemId => _header.ItemId; + internal ItemType ItemType => Header.ItemType; + private int ItemId => Header.ItemId; public float V1y { set => V1.y = value; } public float V2y { set => V2.y = value; } - public override string ToString() => $"LineCollider[{_header.ItemId}] ({V1.x}/{V1.y}@{ZLow}) -> ({V2.x}/{V2.y}@{ZHigh}) at ({Normal.x}/{Normal.y}), len: {_length}"; + public override string ToString() => $"LineCollider[{Header.ItemId}] ({V1.x}/{V1.y}@{ZLow}) -> ({V2.x}/{V2.y}@{ZHigh}) at ({Normal.x}/{Normal.y}), len: {_length}"; - public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( + public ColliderBounds Bounds => new ColliderBounds(Header.ItemId, Header.Id, new Aabb( math.min(V1.x, V2.x), math.max(V1.x, V2.x), math.min(V1.y, V2.y), @@ -56,7 +56,7 @@ internal struct LineCollider : ICollider public LineCollider(float2 v1, float2 v2, float zLow, float zHigh, ColliderInfo info, ColliderType type = ColliderType.Line) : this() { - _header.Init(info, type); + Header.Init(info, type); V1 = v1; V2 = v2; ZLow = zLow; @@ -66,8 +66,8 @@ public LineCollider(float2 v1, float2 v2, float zLow, float zHigh, ColliderInfo public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[_header.Id]); + Header.Id = colliderId; + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), @@ -231,10 +231,10 @@ public void Collide(ref BallState ball, ref NativeQueue.ParallelWrite in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); - BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); + BallCollider.Collide3DWall(ref ball, in Header.Material, in collEvent, in collEvent.HitNormal, ref random); - if (dot <= -_header.Threshold) { - Collider.FireHitEvent(ref ball, ref hitEvents, in _header); + if (dot <= -Header.Threshold) { + Collider.FireHitEvent(ref ball, ref hitEvents, in Header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs index d21bd4e88..4748b85bf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs @@ -24,9 +24,9 @@ namespace VisualPinball.Unity { internal struct LineSlingshotCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; public readonly float2 V1; public readonly float2 V2; @@ -38,7 +38,7 @@ internal struct LineSlingshotCollider : ICollider private readonly float _force; - public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( + public ColliderBounds Bounds => new ColliderBounds(Header.ItemId, Header.Id, new Aabb( math.min(V1.x, V2.x), math.max(V1.x, V2.x), math.min(V1.y, V2.y), @@ -49,7 +49,7 @@ internal struct LineSlingshotCollider : ICollider public LineSlingshotCollider(float force, float2 v1, float2 v2, float zLow, float zHigh, ColliderInfo info) : this() { - _header.Init(info, ColliderType.LineSlingShot); + Header.Init(info, ColliderType.LineSlingShot); _force = force; V1 = v1; V2 = v2; @@ -60,8 +60,8 @@ public LineSlingshotCollider(float force, float2 v1, float2 v2, float zLow, floa public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[_header.Id]); + Header.Id = colliderId; + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), @@ -133,9 +133,9 @@ public void Collide(ref BallState ball, ref NativeQueue.ParallelWrite ball.Velocity -= hitNormal * force; } - BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in hitNormal, ref random); + BallCollider.Collide3DWall(ref ball, in Header.Material, in collEvent, in hitNormal, ref random); - if (/*m_obj &&*/ _header.FireEvents /*&& !m_psurface->m_disabled*/ && threshold) { // todo enabled + if (/*m_obj &&*/ Header.FireEvents /*&& !m_psurface->m_disabled*/ && threshold) { // todo enabled // is this the same place as last event? if same then ignore it var distLs = math.lengthsq(ball.EventPosition - ball.Position); @@ -143,7 +143,7 @@ public void Collide(ref BallState ball, ref NativeQueue.ParallelWrite // !! magic distance, must be a new place if only by a little if (distLs > 0.25f) { - events.Enqueue(new EventData(EventId.SurfaceEventsSlingshot, _header.ItemId, ball.Id, true)); + events.Enqueue(new EventData(EventId.SurfaceEventsSlingshot, Header.ItemId, ball.Id, true)); // todo slingshot animation // m_slingshotanim.m_TimeReset = g_pplayer->m_time_msec + 100; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs index 5af4cdd6f..86e15cb66 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs @@ -24,9 +24,9 @@ namespace VisualPinball.Unity { internal struct LineZCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; public float2 XY; private readonly float _zLow; @@ -34,7 +34,7 @@ internal struct LineZCollider : ICollider public float XyY { set => XY.y = value; } - public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb ( + public ColliderBounds Bounds => new ColliderBounds(Header.ItemId, Header.Id, new Aabb ( XY.x, XY.x, XY.y, @@ -45,8 +45,8 @@ internal struct LineZCollider : ICollider public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[_header.Id]); + Header.Id = colliderId; + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), @@ -57,7 +57,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray.ParallelWrite in int ballId, in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); - BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); + BallCollider.Collide3DWall(ref ball, in Header.Material, in collEvent, in collEvent.HitNormal, ref random); - if (dot <= -_header.Threshold) { - Collider.FireHitEvent(ref ball, ref hitEvents, in _header); + if (dot <= -Header.Threshold) { + Collider.FireHitEvent(ref ball, ref hitEvents, in Header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index c438038fc..74d4cd718 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -25,28 +25,28 @@ namespace VisualPinball.Unity { internal struct PlaneCollider : ICollider { - public int Id => _header.Id; - public PhysicsMaterialData Material => _header.Material; - + public int Id => Header.Id; + public PhysicsMaterialData Material => Header.Material; + - private ColliderHeader _header; + public ColliderHeader Header; private readonly float3 _normal; private readonly float _distance; - public ColliderBounds Bounds => new(_header.ItemId, _header.Id, new Aabb(float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue)); + public ColliderBounds Bounds => new(Header.ItemId, Header.Id, new Aabb(float.MinValue, float.MaxValue, float.MinValue, float.MaxValue, float.MinValue, float.MaxValue)); public PlaneCollider(float3 normal, float distance, ColliderInfo info) : this() { - _header.Init(info, ColliderType.Plane); + Header.Init(info, ColliderType.Plane); _normal = normal; _distance = distance; } public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[_header.Id]); + Header.Id = colliderId; + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), @@ -55,7 +55,7 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray $"PlaneCollider[{_header.ItemId}] {_distance} at ({_normal.x}/{_normal.y}/{_normal.z})"; + public override string ToString() => $"PlaneCollider[{Header.ItemId}] {_distance} at ({_normal.x}/{_normal.y}/{_normal.z})"; #region Narrowphase @@ -125,7 +125,7 @@ public float HitTest(ref CollisionEventData collEvent, in BallState ball, float public void Collide(ref BallState ball, in CollisionEventData collEvent, ref Random random) { - BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); + BallCollider.Collide3DWall(ref ball, in Header.Material, in collEvent, in collEvent.HitNormal, ref random); // distance from plane to ball surface var bnd = math.dot(_normal, ball.Position) - ball.Radius - _distance; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs index 66020600a..f013991f9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs @@ -24,13 +24,13 @@ namespace VisualPinball.Unity { internal struct PointCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; public readonly float3 P; - public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( + public ColliderBounds Bounds => new ColliderBounds(Header.ItemId, Header.Id, new Aabb( P.x, P.x, P.y, @@ -41,14 +41,14 @@ internal struct PointCollider : ICollider public PointCollider(float3 p, ColliderInfo info) : this() { - _header.Init(info, ColliderType.Point); + Header.Init(info, ColliderType.Point); P = p; } public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[_header.Id]); + Header.Id = colliderId; + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), @@ -139,10 +139,10 @@ public void Collide(ref BallState ball, ref NativeQueue.ParallelWrit in CollisionEventData collEvent, ref Random random) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); - BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in collEvent.HitNormal, ref random); + BallCollider.Collide3DWall(ref ball, in Header.Material, in collEvent, in collEvent.HitNormal, ref random); - if (dot <= -_header.Threshold) { - Collider.FireHitEvent(ref ball, ref hitEvents, in _header); + if (dot <= -Header.Threshold) { + Collider.FireHitEvent(ref ball, ref hitEvents, in Header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs index a02870024..b1131f730 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs @@ -25,9 +25,9 @@ namespace VisualPinball.Unity { internal struct TriangleCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; public readonly float3 Rgv0; public readonly float3 Rgv1; @@ -36,9 +36,9 @@ internal struct TriangleCollider : ICollider public float3 Normal() => _normal; - public override string ToString() => $"TriangleCollider[{_header.ItemId}] ({Rgv0.x}/{Rgv0.y}/{Rgv0.z}), ({Rgv1.x}/{Rgv1.y}/{Rgv1.z}), ({Rgv2.x}/{Rgv2.y}/{Rgv2.z}) at ({_normal.x}/{_normal.y/_normal.z})"; + public override string ToString() => $"TriangleCollider[{Header.ItemId}] ({Rgv0.x}/{Rgv0.y}/{Rgv0.z}), ({Rgv1.x}/{Rgv1.y}/{Rgv1.z}), ({Rgv2.x}/{Rgv2.y}/{Rgv2.z}) at ({_normal.x}/{_normal.y/_normal.z})"; - public ColliderBounds Bounds => new ColliderBounds(_header.ItemId, _header.Id, new Aabb( + public ColliderBounds Bounds => new ColliderBounds(Header.ItemId, Header.Id, new Aabb( math.min(Rgv0.x, math.min(Rgv1.x, Rgv2.x)), math.max(Rgv0.x, math.max(Rgv1.x, Rgv2.x)), math.min(Rgv0.y, math.min(Rgv1.y, Rgv2.y)), @@ -49,7 +49,7 @@ internal struct TriangleCollider : ICollider public TriangleCollider(float3 rgv0, float3 rgv1, float3 rgv2, ColliderInfo info) : this() { - _header.Init(info, ColliderType.Triangle); + Header.Init(info, ColliderType.Triangle); Rgv0 = rgv0; Rgv1 = rgv1; Rgv2 = rgv2; @@ -61,8 +61,8 @@ public TriangleCollider(float3 rgv0, float3 rgv1, float3 rgv2, ColliderInfo info public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[_header.Id]); + Header.Id = colliderId; + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), @@ -157,7 +157,7 @@ public float HitTest(ref CollisionEventData collEvent, in InsideOfs insideOfs, i if (pointInTriangle) { - if (_header.ItemType == ItemType.Trigger && bnd < 0 == insideOfs.IsOutsideOf(_header.ItemId, ball.Id)) { + if (Header.ItemType == ItemType.Trigger && bnd < 0 == insideOfs.IsOutsideOf(Header.ItemId, ball.Id)) { collEvent.HitFlag = bnd > 0; } @@ -183,11 +183,11 @@ public void Collide(ref BallState ball, ref NativeQueue.ParallelWrite in CollisionEventData collEvent, ref Random random) { var dot = -math.dot(collEvent.HitNormal, ball.Velocity); - BallCollider.Collide3DWall(ref ball, in _header.Material, in collEvent, in _normal, ref random); + BallCollider.Collide3DWall(ref ball, in Header.Material, in collEvent, in _normal, ref random); - if (_header.FireEvents && dot >= _header.Threshold && _header.IsPrimitive) { + if (Header.FireEvents && dot >= Header.Threshold && Header.IsPrimitive) { // todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in _header); + Collider.FireHitEvent(ref ball, ref hitEvents, in Header); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs index f00836a60..452748854 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs @@ -22,14 +22,14 @@ internal static void Update(ref ContactBufferElement contact, ref BallState ball { ref var collEvent = ref contact.CollEvent; if (collEvent.ColliderId > -1) { // collide with static collider - var coll = state.GetCollider(collEvent.ColliderId); - if (coll.Type == ColliderType.Flipper) { + var collHeader = state.GetColliderHeader(collEvent.ColliderId); + if (collHeader.Type == ColliderType.Flipper) { ref var flipperCollider = ref state.Colliders.GetFlipperCollider(collEvent.ColliderId); ref var flipperState = ref state.GetFlipperState(collEvent.ColliderId); flipperCollider.Contact(ref ball, ref flipperState.Movement, in collEvent, in flipperState.Static, in flipperState.Velocity, hitTime, in state.Env.Gravity); } else { - Collider.Contact(ref coll, ref ball, in collEvent, hitTime, in state.Env.Gravity); + Collider.Contact(in collHeader, ref ball, in collEvent, hitTime, in state.Env.Gravity); } } else if (collEvent.BallId != 0) { // collide with ball BallCollider.HandleStaticContact(ref ball, in collEvent, state.Colliders.GetFriction(contact.CollEvent.ColliderId), hitTime, state.Env.Gravity); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs index 663179bf2..25847bf6e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs @@ -24,13 +24,13 @@ internal static class BumperCollider { public static void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, ref CollisionEventData collEvent, ref BumperRingAnimationState ringState, ref BumperSkirtAnimationState skirtState, - in Collider collider, in BumperStaticState state, ref Random random) + in ColliderHeader collHeader, in BumperStaticState state, ref Random random) { // todo // if (!m_enabled) return; var dot = math.dot(collEvent.HitNormal, ball.Velocity); // needs to be computed before Collide3DWall()! - var material = collider.Material; + var material = collHeader.Material; BallCollider.Collide3DWall(ref ball, in material, in collEvent, in collEvent.HitNormal, ref random); // reflect ball from wall if (state.HitEvent && dot <= -state.Threshold) { // if velocity greater than threshold level @@ -41,7 +41,7 @@ public static void Collide(ref BallState ball, ref NativeQueue.Parall skirtState.HitEvent = true; skirtState.BallPosition = ball.Position; - events.Enqueue(new EventData(EventId.HitEventsHit, collider.ItemId, ball.Id, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, collHeader.ItemId, ball.Id, true)); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs index fe0374dec..cebdae3bf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs @@ -26,9 +26,9 @@ namespace VisualPinball.Unity { internal struct FlipperCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; private readonly CircleCollider _hitCircleBase; private readonly float _zLow; @@ -43,7 +43,7 @@ internal struct FlipperCollider : ICollider public FlipperCollider(CircleCollider hitCircleBase, float flipperRadius, float startRadius, float endRadius, float startAngle, float endAngle, ColliderInfo info) : this() { var bounds = hitCircleBase.Bounds; - _header.Init(info, ColliderType.Flipper); + Header.Init(info, ColliderType.Flipper); _hitCircleBase = hitCircleBase; _zLow = bounds.Aabb.ZLow; _zHigh = bounds.Aabb.ZHigh; @@ -69,7 +69,7 @@ public FlipperCollider(CircleCollider hitCircleBase, float flipperRadius, float aabb = ExtendBoundsAtExtreme(aabb, c, flipperRadius, r2, r3, a0, a1, 90f); aabb = ExtendBoundsAtExtreme(aabb, c, flipperRadius, r2, r3, a0, a1, 180f); - Bounds = new ColliderBounds(_header.ItemId, _header.Id, aabb); + Bounds = new ColliderBounds(Header.ItemId, Header.Id, aabb); } private static Aabb ExtendBoundsAtExtreme(Aabb aabb, float2 c, float length, float endRadius, float startRadius, float startAngle, float endAngle, float angle) @@ -135,11 +135,11 @@ private static float ClampDegrees(float angle) public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; + Header.Id = colliderId; var bounds = Bounds; bounds.ColliderId = colliderId; Bounds = bounds; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[_header.Id]); + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), @@ -666,7 +666,7 @@ public void Contact(ref BallState ball, ref FlipperMovementState movementState, // first check for slippage var slip = vRel - normVel * normal; // calc the tangential slip velocity - var maxFriction = j * _header.Material.Friction; + var maxFriction = j * Header.Material.Friction; var slipSpeed = math.length(slip); float3 slipDir; float3 crossF; @@ -842,7 +842,7 @@ public void Collide(ref BallState ball, ref CollisionEventData collEvent, ref Fl * We use a heuristic model which decreases the COR according to a falloff parameter: * 0 = no falloff, 1 = half the COR at 1 m/s (18.53 speed units) */ - var epsilon = Math.ElasticityWithFalloff(_header.Material.Elasticity, _header.Material.ElasticityFalloff, bnv); + var epsilon = Math.ElasticityWithFalloff(Header.Material.Elasticity, Header.Material.ElasticityFalloff, bnv); if (tricks.UseFlipperTricksPhysics) epsilon *= tricks.ElasticityMultiplier; @@ -899,7 +899,7 @@ public void Collide(ref BallState ball, ref CollisionEventData collEvent, ref Fl kt += math.dot(tangent, math.cross(pv13, rF)); // flipper only has angular response // friction impulse can't be greater than coefficient of friction times collision impulse (Coulomb friction cone) - var maxFriction = _header.Material.Friction * impulse; + var maxFriction = Header.Material.Friction * impulse; var jt = math.clamp(-vt / kt, -maxFriction, maxFriction); ball.ApplySurfaceImpulse( @@ -915,11 +915,11 @@ public void Collide(ref BallState ball, ref CollisionEventData collEvent, ref Fl var flipperHit = hitData.HitMomentBit ? -1.0f : -bnv; // move event processing to end of collision handler... if (flipperHit < 0f) { // simple hit event - events.Enqueue(new EventData(EventId.HitEventsHit, _header.ItemId, ballId, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, Header.ItemId, ballId, true)); } else { // collision velocity (normal to face) - events.Enqueue(new EventData(EventId.FlipperEventsCollide, _header.ItemId, ballId, flipperHit)); + events.Enqueue(new EventData(EventId.FlipperEventsCollide, Header.ItemId, ballId, flipperHit)); } } movementState.LastHitTime = timeMsec; // keep resetting until idle for 250 milliseconds diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs index 67951dbe2..7efdceb39 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs @@ -23,9 +23,9 @@ namespace VisualPinball.Unity { internal struct GateCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; public readonly LineCollider LineSeg0; public readonly LineCollider LineSeg1; @@ -34,7 +34,7 @@ internal struct GateCollider : ICollider public GateCollider(in LineCollider lineSeg0, in LineCollider lineSeg1, ColliderInfo info) : this() { - _header.Init(info, ColliderType.Gate); + Header.Init(info, ColliderType.Gate); LineSeg0 = lineSeg0; LineSeg1 = lineSeg1; @@ -43,11 +43,11 @@ public GateCollider(in LineCollider lineSeg0, in LineCollider lineSeg1, Collider public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; + Header.Id = colliderId; var bounds = Bounds; bounds.ColliderId = colliderId; Bounds = bounds; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[_header.Id]); + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), @@ -86,7 +86,7 @@ public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, #region Collision public static void Collide(ref BallState ball, ref CollisionEventData collEvent, ref GateMovementState movementState, - ref NativeQueue.ParallelWriter events, in Collider coll, in GateStaticState state) + ref NativeQueue.ParallelWriter events, in ColliderHeader collHeader, in GateStaticState state) { var dot = math.dot(collEvent.HitNormal, ball.Velocity); var h = state.Height * 0.5f; @@ -114,7 +114,7 @@ public static void Collide(ref BallState ball, ref CollisionEventData collEvent, movementState.AngleSpeed = -movementState.AngleSpeed; } - Collider.FireHitEvent(ref ball, ref events, in coll.Header); + Collider.FireHitEvent(ref ball, ref events, in collHeader); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs index a26479ee3..4b92c7c00 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/TargetCollider.cs @@ -23,33 +23,33 @@ internal static class TargetCollider { public static void DropTargetCollide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, ref DropTargetAnimationState animation, in float3 normal, in CollisionEventData collEvent, - in Collider coll, ref Random random) + in ColliderHeader collHeader, ref Random random) { if (animation.IsDropped) { return; } var dot = -math.dot(collEvent.HitNormal, ball.Velocity); - BallCollider.Collide3DWall(ref ball, in coll.Header.Material, in collEvent, in normal, ref random); + BallCollider.Collide3DWall(ref ball, in collHeader.Material, in collEvent, in normal, ref random); - if (coll.FireEvents && dot >= coll.Threshold && !animation.IsDropped) { + if (collHeader.FireEvents && dot >= collHeader.Threshold && !animation.IsDropped) { animation.HitEvent = true; //todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in coll.Header); + Collider.FireHitEvent(ref ball, ref hitEvents, in collHeader); } } public static void HitTargetCollide(ref BallState ball, ref NativeQueue.ParallelWriter hitEvents, ref HitTargetAnimationData animationData, in float3 normal, in CollisionEventData collEvent, - in Collider coll, ref Random random) + in ColliderHeader collHeader, ref Random random) { var dot = -math.dot(collEvent.HitNormal, ball.Velocity); - BallCollider.Collide3DWall(ref ball, in coll.Header.Material, in collEvent, in normal, ref random); + BallCollider.Collide3DWall(ref ball, in collHeader.Material, in collEvent, in normal, ref random); - if (coll.FireEvents && dot >= coll.Threshold) { + if (collHeader.FireEvents && dot >= collHeader.Threshold) { animationData.HitEvent = true; //todo m_obj->m_currentHitThreshold = dot; - Collider.FireHitEvent(ref ball, ref hitEvents, in coll.Header); + Collider.FireHitEvent(ref ball, ref hitEvents, in collHeader); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs index 3e323f382..e10570099 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs @@ -25,9 +25,9 @@ namespace VisualPinball.Unity { internal struct PlungerCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; public LineCollider LineSegBase; public LineZCollider JointBase0; @@ -37,7 +37,7 @@ internal struct PlungerCollider : ICollider public PlungerCollider(PlungerComponent comp, PlungerColliderComponent collComp, ColliderInfo info) : this() { - _header.Init(info, ColliderType.Plunger); + Header.Init(info, ColliderType.Plunger); var zHeight = comp.PositionZ; var x = comp.Position.x - comp.Width; @@ -50,7 +50,7 @@ public PlungerCollider(PlungerComponent comp, PlungerColliderComponent collComp, JointBase1 = new LineZCollider(new float2(x2, y), zHeight, zHeight + Plunger.PlungerHeight, info); var frameEnd = comp.Position.y - collComp.Stroke; - Bounds = new ColliderBounds(_header.ItemId, _header.Id, new Aabb( + Bounds = new ColliderBounds(Header.ItemId, Header.Id, new Aabb( x - 0.1f, x2 + 0.1f, frameEnd - 0.1f, @@ -65,8 +65,8 @@ public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray, BlobPtr>(ref colliders[_header.Id]); + Header.Id = colliderId; + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs index 5f3c17054..42bfc1a17 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs @@ -24,9 +24,9 @@ namespace VisualPinball.Unity { internal struct SpinnerCollider : ICollider { - public int Id => _header.Id; + public int Id => Header.Id; - private ColliderHeader _header; + public ColliderHeader Header; public readonly LineCollider LineSeg0; public readonly LineCollider LineSeg1; @@ -35,7 +35,7 @@ internal struct SpinnerCollider : ICollider public SpinnerCollider(SpinnerComponent component, float height, ColliderInfo info) : this() { - _header.Init(info, ColliderType.Spinner); + Header.Init(info, ColliderType.Spinner); var halfLength = component.Length * 0.5f; @@ -60,11 +60,11 @@ public SpinnerCollider(SpinnerComponent component, float height, ColliderInfo in public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) { - _header.Id = colliderId; + Header.Id = colliderId; var bounds = Bounds; bounds.ColliderId = colliderId; Bounds = bounds; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[_header.Id]); + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs index 131749c67..470e14c63 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerCollider.cs @@ -25,22 +25,22 @@ internal static class TriggerCollider { public static void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, ref CollisionEventData collEvent, ref InsideOfs insideOfs, - ref TriggerAnimationState animation, in Collider coll) + ref TriggerAnimationState animation, in ColliderHeader collHeader) { - var insideOf = insideOfs.IsInsideOf(coll.ItemId, ball.Id); + var insideOf = insideOfs.IsInsideOf(collHeader.ItemId, ball.Id); if (collEvent.HitFlag == insideOf) { // Hit == NotAlreadyHit ball.Position += PhysicsConstants.StaticTime * ball.Velocity; // move ball slightly forward if (!insideOf) { - insideOfs.SetInsideOf(coll.ItemId, ball.Id); + insideOfs.SetInsideOf(collHeader.ItemId, ball.Id); animation.HitEvent = true; - events.Enqueue(new EventData(EventId.HitEventsHit, coll.ItemId, ball.Id, true)); + events.Enqueue(new EventData(EventId.HitEventsHit, collHeader.ItemId, ball.Id, true)); } else { - insideOfs.SetOutsideOf(coll.ItemId, ball.Id); + insideOfs.SetOutsideOf(collHeader.ItemId, ball.Id); animation.UnHitEvent = true; - events.Enqueue(new EventData(EventId.HitEventsUnhit, coll.ItemId, ball.Id, true)); + events.Enqueue(new EventData(EventId.HitEventsUnhit, collHeader.ItemId, ball.Id, true)); } } } From fc2db9aa36c422bb983f751de000777a58c098cc Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 25 Oct 2023 22:15:16 +0200 Subject: [PATCH 142/159] jobs: Simplify collider reference. --- .../Physics/Collider/ColliderReference.cs | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs index dbcd10492..8cc81a5ed 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs @@ -35,8 +35,7 @@ public struct ColliderReference : IDisposable internal NativeList TriangleColliders; internal NativeList PlaneColliders; - private NativeHashMap _lookup; - private int _currentIndex; + public NativeList Lookup; public ColliderReference(Allocator allocator) { @@ -52,8 +51,7 @@ public ColliderReference(Allocator allocator) SpinnerColliders = new NativeList(allocator); TriangleColliders = new NativeList(allocator); PlaneColliders = new NativeList(allocator); - _currentIndex = 0; - _lookup = new NativeHashMap(8192, allocator); + Lookup = new NativeList(allocator); } public void Dispose() @@ -72,17 +70,17 @@ public void Dispose() PlaneColliders.Dispose(); } - public int Count => _lookup.Count; + public int Count => Lookup.Length; public ICollider this[int i] => LookupCollider(i); private ICollider LookupCollider(int i) { - if (_lookup.ContainsKey(i)) { + if (i < 0 || i >= Lookup.Length) { throw new IndexOutOfRangeException($"Invalid index {i} when looking up collider."); } - var lookup = _lookup[i]; + var lookup = Lookup[i]; switch (lookup.Type) { case ColliderType.Circle: return CircleColliders.GetElementAsRef(lookup.Index); case ColliderType.Flipper: return FlipperColliders.GetElementAsRef(lookup.Index); @@ -104,89 +102,88 @@ private ICollider LookupCollider(int i) internal void Add(CircleCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.Circle, CircleColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.Circle, CircleColliders.Length)); CircleColliders.Add(collider); } internal void Add(FlipperCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.Flipper, FlipperColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.Flipper, FlipperColliders.Length)); FlipperColliders.Add(collider); } internal void Add(GateCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.Gate, GateColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.Gate, GateColliders.Length)); GateColliders.Add(collider); } internal void Add(Line3DCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.Line3D, Line3DColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.Line3D, Line3DColliders.Length)); Line3DColliders.Add(collider); } internal void Add(LineSlingshotCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.LineSlingShot, LineSlingshotColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.LineSlingShot, LineSlingshotColliders.Length)); LineSlingshotColliders.Add(collider); } internal void Add(LineCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.Line, LineColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.Line, LineColliders.Length)); LineColliders.Add(collider); } internal void Add(LineZCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.LineZ, LineZColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.LineZ, LineZColliders.Length)); LineZColliders.Add(collider); } internal void Add(PlungerCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.Plunger, PlungerColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.Plunger, PlungerColliders.Length)); PlungerColliders.Add(collider); } internal void Add(PointCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.Point, PointColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.Point, PointColliders.Length)); PointColliders.Add(collider); } internal void Add(SpinnerCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.Spinner, SpinnerColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.Spinner, SpinnerColliders.Length)); SpinnerColliders.Add(collider); } internal void Add(TriangleCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.Triangle, TriangleColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.Triangle, TriangleColliders.Length)); TriangleColliders.Add(collider); } internal void Add(PlaneCollider collider) { - _lookup[_currentIndex++] = new Lookup(ColliderType.Plane, PlaneColliders.Length); + Lookup.Add(new ColliderLookup(ColliderType.Plane, PlaneColliders.Length)); PlaneColliders.Add(collider); } #endregion - private readonly struct Lookup + public readonly struct ColliderLookup { public readonly ColliderType Type; public readonly int Index; - public Lookup(ColliderType type, int index) + public ColliderLookup(ColliderType type, int index) { Type = type; Index = index; } } - } } From 956a45c46a3992f4f7e2f6945cf8e85e86bedfda Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 25 Oct 2023 22:43:13 +0200 Subject: [PATCH 143/159] jobs: Set collider ID before allocation. --- .../Physics/Collider/CircleCollider.cs | 5 ++-- .../Physics/Collider/ColliderReference.cs | 27 +++++++++++++++++++ .../Physics/Collider/ICollider.cs | 2 +- .../Physics/Collider/Line3DCollider.cs | 6 +---- .../Physics/Collider/LineCollider.cs | 3 +-- .../Physics/Collider/LineSlingshotCollider.cs | 3 +-- .../Physics/Collider/LineZCollider.cs | 3 +-- .../Physics/Collider/PlaneCollider.cs | 3 +-- .../Physics/Collider/PointCollider.cs | 3 +-- .../Physics/Collider/TriangleCollider.cs | 3 +-- .../Collision/ColliderAllocationJob.cs | 25 +++++++++-------- .../VPT/Flipper/FlipperCollider.cs | 7 +++-- .../VPT/Gate/GateCollider.cs | 8 ++---- .../VPT/Plunger/PlungerCollider.cs | 8 ++---- .../VPT/Spinner/SpinnerCollider.cs | 8 ++---- 15 files changed, 58 insertions(+), 56 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs index 42394c455..fc591d44c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs @@ -52,10 +52,9 @@ public CircleCollider(float2 center, float radius, float zLow, float zHigh, Coll _zLow = zLow; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[colliderId]); + ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( UnsafeUtility.AddressOf(ref collider), diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs index 8cc81a5ed..37b31282c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs @@ -102,72 +102,99 @@ private ICollider LookupCollider(int i) internal void Add(CircleCollider collider) { + collider.Header.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Circle, CircleColliders.Length)); CircleColliders.Add(collider); } internal void Add(FlipperCollider collider) { + collider.Header.Id = Lookup.Length; + var bounds = collider.Bounds; + bounds.ColliderId = collider.Header.Id; + collider.Bounds = bounds; Lookup.Add(new ColliderLookup(ColliderType.Flipper, FlipperColliders.Length)); FlipperColliders.Add(collider); } internal void Add(GateCollider collider) { + collider.Header.Id = Lookup.Length; + var bounds = collider.Bounds; + bounds.ColliderId = collider.Header.Id; + collider.Bounds = bounds; Lookup.Add(new ColliderLookup(ColliderType.Gate, GateColliders.Length)); GateColliders.Add(collider); } internal void Add(Line3DCollider collider) { + collider.Header.Id = Lookup.Length; + var bounds = collider.Bounds; + bounds.ColliderId = collider.Header.Id; + collider.Bounds = bounds; Lookup.Add(new ColliderLookup(ColliderType.Line3D, Line3DColliders.Length)); Line3DColliders.Add(collider); } internal void Add(LineSlingshotCollider collider) { + collider.Header.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.LineSlingShot, LineSlingshotColliders.Length)); LineSlingshotColliders.Add(collider); } internal void Add(LineCollider collider) { + collider.Header.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Line, LineColliders.Length)); LineColliders.Add(collider); } internal void Add(LineZCollider collider) { + collider.Header.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.LineZ, LineZColliders.Length)); LineZColliders.Add(collider); } internal void Add(PlungerCollider collider) { + collider.Header.Id = Lookup.Length; + var bounds = collider.Bounds; + bounds.ColliderId = collider.Header.Id; + collider.Bounds = bounds; Lookup.Add(new ColliderLookup(ColliderType.Plunger, PlungerColliders.Length)); PlungerColliders.Add(collider); } internal void Add(PointCollider collider) { + collider.Header.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Point, PointColliders.Length)); PointColliders.Add(collider); } internal void Add(SpinnerCollider collider) { + collider.Header.Id = Lookup.Length; + var bounds = collider.Bounds; + bounds.ColliderId = collider.Header.Id; + collider.Bounds = bounds; Lookup.Add(new ColliderLookup(ColliderType.Spinner, SpinnerColliders.Length)); SpinnerColliders.Add(collider); } internal void Add(TriangleCollider collider) { + collider.Header.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Triangle, TriangleColliders.Length)); TriangleColliders.Add(collider); } internal void Add(PlaneCollider collider) { + collider.Header.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Plane, PlaneColliders.Length)); PlaneColliders.Add(collider); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ICollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ICollider.cs index a17605b2e..319efa6d6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ICollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ICollider.cs @@ -21,7 +21,7 @@ namespace VisualPinball.Unity public interface ICollider { int Id { get; } - void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int index); + void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders); ColliderBounds Bounds { get; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs index 0f7b3ee54..5219f716d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs @@ -83,12 +83,8 @@ public Line3DCollider(float3 v1, float3 v2, ColliderInfo info) : this() )); } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; - var bounds = Bounds; - bounds.ColliderId = colliderId; - Bounds = bounds; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index 129219577..052015189 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -64,9 +64,8 @@ public LineCollider(float2 v1, float2 v2, float zLow, float zHigh, ColliderInfo CalcNormal(); } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs index 4748b85bf..ca10b049d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs @@ -58,9 +58,8 @@ public LineSlingshotCollider(float force, float2 v1, float2 v2, float zLow, floa CalcNormal(); } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs index 86e15cb66..e1c736c52 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs @@ -43,9 +43,8 @@ internal struct LineZCollider : ICollider _zHigh )); - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index 74d4cd718..48874cf52 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -43,9 +43,8 @@ public PlaneCollider(float3 normal, float distance, ColliderInfo info) : this() _distance = distance; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs index f013991f9..6014efdc9 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs @@ -45,9 +45,8 @@ public PointCollider(float3 p, ColliderInfo info) : this() P = p; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs index b1131f730..5880a23af 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs @@ -59,9 +59,8 @@ public TriangleCollider(float3 rgv0, float3 rgv1, float3 rgv2, ColliderInfo info _normal = math.normalizesafe(math.cross(e0, e1)); } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs index 1e8824365..e9791d60d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs @@ -83,7 +83,6 @@ public ColliderAllocationJob(ref ColliderReference colliderList) : this() public void Execute() { var builder = new BlobBuilder(Allocator.Temp); - var colliderId = 0; ref var root = ref builder.ConstructRoot(); var count = _circleColliders.Length + _flipperColliders.Length + _gateColliders.Length + _line3DColliders.Length + _lineSlingshotColliders.Length + _lineColliders.Length + _lineZColliders.Length + _plungerColliders.Length @@ -93,40 +92,40 @@ public void Execute() // copy generated colliders into blob array for (var i = 0; i < _circleColliders.Length; i++) { - _circleColliders[i].Allocate(builder, ref colliders, colliderId++); + _circleColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _flipperColliders.Length; i++) { - _flipperColliders[i].Allocate(builder, ref colliders, colliderId++); + _flipperColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _gateColliders.Length; i++) { - _gateColliders[i].Allocate(builder, ref colliders, colliderId++); + _gateColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _line3DColliders.Length; i++) { - _line3DColliders[i].Allocate(builder, ref colliders, colliderId++); + _line3DColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _lineSlingshotColliders.Length; i++) { - _lineSlingshotColliders[i].Allocate(builder, ref colliders, colliderId++); + _lineSlingshotColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _lineColliders.Length; i++) { - _lineColliders[i].Allocate(builder, ref colliders, colliderId++); + _lineColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _lineZColliders.Length; i++) { - _lineZColliders[i].Allocate(builder, ref colliders, colliderId++); + _lineZColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _planeColliders.Length; i++) { - _planeColliders[i].Allocate(builder, ref colliders, colliderId++); + _planeColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _plungerColliders.Length; i++) { - _plungerColliders[i].Allocate(builder, ref colliders, colliderId++); + _plungerColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _pointColliders.Length; i++) { - _pointColliders[i].Allocate(builder, ref colliders, colliderId++); + _pointColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _spinnerColliders.Length; i++) { - _spinnerColliders[i].Allocate(builder, ref colliders, colliderId++); + _spinnerColliders[i].Allocate(builder, ref colliders); } for (var i = 0; i < _triangleColliders.Length; i++) { - _triangleColliders[i].Allocate(builder, ref colliders, colliderId++); + _triangleColliders[i].Allocate(builder, ref colliders); } BlobAsset[0] = builder.CreateBlobAssetReference(Allocator.Persistent); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs index cebdae3bf..a7dfcd404 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs @@ -34,7 +34,7 @@ internal struct FlipperCollider : ICollider private readonly float _zLow; private readonly float _zHigh; - public ColliderBounds Bounds { get; private set; } + public ColliderBounds Bounds { get; set; } public static readonly Logger Logger = LogManager.GetCurrentClassLogger(); @@ -133,11 +133,10 @@ private static float ClampDegrees(float angle) return deg > 180 ? deg - 360 : deg; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; var bounds = Bounds; - bounds.ColliderId = colliderId; + bounds.ColliderId = Header.Id; Bounds = bounds; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs index 7efdceb39..f0419345d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs @@ -30,7 +30,7 @@ internal struct GateCollider : ICollider public readonly LineCollider LineSeg0; public readonly LineCollider LineSeg1; - public ColliderBounds Bounds { get; private set; } + public ColliderBounds Bounds { get; set; } public GateCollider(in LineCollider lineSeg0, in LineCollider lineSeg1, ColliderInfo info) : this() { @@ -41,12 +41,8 @@ public GateCollider(in LineCollider lineSeg0, in LineCollider lineSeg1, Collider Bounds = LineSeg0.Bounds; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; - var bounds = Bounds; - bounds.ColliderId = colliderId; - Bounds = bounds; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs index e10570099..dfe37cb51 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs @@ -33,7 +33,7 @@ internal struct PlungerCollider : ICollider public LineZCollider JointBase0; public LineZCollider JointBase1; - public ColliderBounds Bounds { get; private set; } + public ColliderBounds Bounds { get; set; } public PlungerCollider(PlungerComponent comp, PlungerColliderComponent collComp, ColliderInfo info) : this() { @@ -60,12 +60,8 @@ public PlungerCollider(PlungerComponent comp, PlungerColliderComponent collComp, )); } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - var bounds = Bounds; - bounds.ColliderId = colliderId; - Bounds = bounds; - Header.Id = colliderId; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs index 42bfc1a17..722f87ef4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs @@ -31,7 +31,7 @@ internal struct SpinnerCollider : ICollider public readonly LineCollider LineSeg0; public readonly LineCollider LineSeg1; - public ColliderBounds Bounds { get; private set; } + public ColliderBounds Bounds { get; set; } public SpinnerCollider(SpinnerComponent component, float height, ColliderInfo info) : this() { @@ -58,12 +58,8 @@ public SpinnerCollider(SpinnerComponent component, float height, ColliderInfo in Bounds = LineSeg0.Bounds; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders, int colliderId) + public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) { - Header.Id = colliderId; - var bounds = Bounds; - bounds.ColliderId = colliderId; - Bounds = bounds; ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); ref var collider = ref builder.Allocate(ref ptr); UnsafeUtility.MemCpy( From d7b9ae756bfc44401f1a38709b15f2264030cbaf Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 25 Oct 2023 23:24:36 +0200 Subject: [PATCH 144/159] jobs: Swap BlobAssetReference with NativeColliders. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 19 +- .../Game/PhysicsPopulateJob.cs | 6 +- .../VisualPinball.Unity/Game/PhysicsState.cs | 116 +--- .../Game/PhysicsStaticCollision.cs | 18 +- .../Game/PhysicsUpdateJob.cs | 2 +- .../Physics/Collider/ColliderReference.cs | 53 +- .../Physics/Collider/Line3DCollider.cs | 2 + .../Physics/Collider/PointCollider.cs | 2 + .../Physics/Collision/ContactPhysics.cs | 5 +- .../Physics/NativeCollider.cs | 630 ++++++++++++++++++ .../Physics/NativeCollider.cs.meta | 3 + .../VPT/ColliderComponent.cs | 9 +- 12 files changed, 734 insertions(+), 131 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index d5dfb53c0..083e502f5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -44,7 +44,7 @@ public class PhysicsEngine : MonoBehaviour [NonSerialized] private AABB _playfieldBounds; [NonSerialized] private InsideOfs _insideOfs; [NonSerialized] private NativeOctree _octree; - [NonSerialized] private BlobAssetReference _colliders; + [NonSerialized] private NativeColliders _colliders; [NonSerialized] private NativeArray _physicsEnv = new(1, Allocator.Persistent); [NonSerialized] private NativeQueue _eventQueue = new(Allocator.Persistent); @@ -180,7 +180,7 @@ private void Start() } // allocate colliders - _colliders = AllocateColliders(ref colliders); + _colliders = new NativeColliders(ref colliders, Allocator.Persistent); // create octree var elapsedMs = sw.Elapsed.TotalMilliseconds; @@ -195,7 +195,7 @@ private void Start() }; populateJob.Run(); _octree = populateJob.Octree; - Debug.Log($"Octree of {_colliders.Value.Colliders.Length} constructed (colliders: {elapsedMs}ms, tree: {sw.Elapsed.TotalMilliseconds}ms)."); + Debug.Log($"Octree of {_colliders.Length} constructed (colliders: {elapsedMs}ms, tree: {sw.Elapsed.TotalMilliseconds}ms)."); // get balls var balls = GetComponentsInChildren(); @@ -381,19 +381,6 @@ private void OnDestroy() #endregion - #region Helpers - - private static BlobAssetReference AllocateColliders(ref ColliderReference managedColliders) - { - var allocateColliderJob = new ColliderAllocationJob(ref managedColliders); - allocateColliderJob.Run(); - var colliders = allocateColliderJob.BlobAsset[0]; - allocateColliderJob.Dispose(); - return colliders; - } - - #endregion - private class ScheduledAction { public readonly ulong ScheduleAt; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs index cefbde893..8713b4e53 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs @@ -10,13 +10,13 @@ namespace VisualPinball.Unity internal struct PhysicsPopulateJob : IJob { [ReadOnly] - public BlobAssetReference Colliders; + public NativeColliders Colliders; public NativeOctree Octree; public void Execute() { - for (var i = 0; i < Colliders.Value.Colliders.Length; i++) { - Octree.Insert(Colliders.GetId(i), Colliders.GetAabb(i)); + for (var i = 0; i < Colliders.Length; i++) { + Octree.Insert(i, Colliders.GetAabb(i)); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index daa7daf1d..393af76de 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -26,7 +26,7 @@ internal struct PhysicsState { internal PhysicsEnv Env; internal NativeOctree Octree; - internal BlobAssetReference Colliders; + internal NativeColliders Colliders; internal NativeQueue.ParallelWriter EventQueue; internal InsideOfs InsideOfs; internal NativeParallelHashMap Balls; @@ -43,7 +43,7 @@ internal struct PhysicsState internal NativeParallelHashSet DisabledCollisionItems; internal bool SwapBallCollisionHandling; - public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAssetReference colliders, + public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref NativeColliders colliders, ref NativeQueue.ParallelWriter eventQueue, ref InsideOfs insideOfs, ref NativeParallelHashMap balls, ref NativeParallelHashMap bumperStates, ref NativeParallelHashMap dropTargetStates, ref NativeParallelHashMap flipperStates, ref NativeParallelHashMap gateStates, @@ -72,87 +72,36 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref BlobAs SwapBallCollisionHandling = swapBallCollisionHandling; } - internal ColliderHeader GetColliderHeader(int colliderId) => Colliders.Value.Colliders[colliderId].Value.Header; + internal ref ColliderHeader GetColliderHeader(int colliderId) => ref Colliders.GetHeader(colliderId); - internal bool IsColliderActive(int colliderId) - { - var collHeader = GetColliderHeader(colliderId); - return !DisabledCollisionItems.Contains(collHeader.ItemId); - } + internal bool IsColliderActive(int colliderId) => !DisabledCollisionItems.Contains(Colliders.GetItemId(colliderId)); #region States - internal ref FlipperState GetFlipperState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return ref FlipperStates.GetValueByRef(collider.ItemId); - } + internal ref FlipperState GetFlipperState(int colliderId) => ref FlipperStates.GetValueByRef(Colliders.GetItemId(colliderId)); - internal ref PlungerState GetPlungerState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return ref PlungerStates.GetValueByRef(collider.ItemId); - } + internal ref PlungerState GetPlungerState(int colliderId) => ref PlungerStates.GetValueByRef(Colliders.GetItemId(colliderId)); - internal ref SpinnerState GetSpinnerState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return ref SpinnerStates.GetValueByRef(collider.ItemId); - } + internal ref SpinnerState GetSpinnerState(int colliderId) => ref SpinnerStates.GetValueByRef(Colliders.GetItemId(colliderId)); - internal ref TriggerState GetTriggerState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return ref TriggerStates.GetValueByRef(collider.ItemId); - } + internal ref TriggerState GetTriggerState(int colliderId) => ref TriggerStates.GetValueByRef(Colliders.GetItemId(colliderId)); - internal ref KickerState GetKickerState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return ref KickerStates.GetValueByRef(collider.ItemId); - } + internal ref KickerState GetKickerState(int colliderId) => ref KickerStates.GetValueByRef(Colliders.GetItemId(colliderId)); - internal bool HasDropTargetState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return DropTargetStates.ContainsKey(collider.ItemId); - } - internal bool HasHitTargetState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return HitTargetStates.ContainsKey(collider.ItemId); - } + internal bool HasDropTargetState(int colliderId) => DropTargetStates.ContainsKey(Colliders.GetItemId(colliderId)); - internal ref DropTargetState GetDropTargetState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return ref DropTargetStates.GetValueByRef(collider.ItemId); - } + internal bool HasHitTargetState(int colliderId) => HitTargetStates.ContainsKey(Colliders.GetItemId(colliderId)); - internal ref HitTargetState GetHitTargetState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return ref HitTargetStates.GetValueByRef(collider.ItemId); - } + internal ref DropTargetState GetDropTargetState(int colliderId) => ref DropTargetStates.GetValueByRef(Colliders.GetItemId(colliderId)); - internal ref BumperState GetBumperState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return ref BumperStates.GetValueByRef(collider.ItemId); - } + internal ref HitTargetState GetHitTargetState(int colliderId) => ref HitTargetStates.GetValueByRef(Colliders.GetItemId(colliderId)); - internal ref GateState GetGateState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return ref GateStates.GetValueByRef(collider.ItemId); - } + internal ref BumperState GetBumperState(int colliderId) => ref BumperStates.GetValueByRef(Colliders.GetItemId(colliderId)); - internal ref SurfaceState GetSurfaceState(int colliderId) - { - var collider = Colliders.Value.Colliders[colliderId].Value; - return ref SurfaceStates.GetValueByRef(collider.ItemId); - } + internal ref GateState GetGateState(int colliderId) => ref GateStates.GetValueByRef(Colliders.GetItemId(colliderId)); + + internal ref SurfaceState GetSurfaceState(int colliderId) => ref SurfaceStates.GetValueByRef(Colliders.GetItemId(colliderId)); #endregion @@ -166,57 +115,57 @@ internal float HitTest(int colliderId, ref BallState ball, ref CollisionEventDat switch (Colliders.GetType(colliderId)) { case ColliderType.Bumper: case ColliderType.Circle: - return Colliders.GetCircleCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, + return Colliders.Circle(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); case ColliderType.Gate: - return Colliders.GetGateCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, + return Colliders.Gate(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); case ColliderType.Line: - return Colliders.GetLineCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, + return Colliders.Line(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); case ColliderType.LineZ: - return Colliders.GetLineZCollider(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + return Colliders.LineZ(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); case ColliderType.Line3D: - return Colliders.GetLine3DCollider(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + return Colliders.Line3D(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); case ColliderType.LineSlingShot: - return Colliders.GetLineSlingshotCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); + return Colliders.LineSlingShot(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); case ColliderType.Point: - return Colliders.GetPointCollider(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + return Colliders.Point(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); case ColliderType.Plane: - return Colliders.GetPlaneCollider(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); + return Colliders.Plane(colliderId).HitTest(ref collEvent, in ball, ball.CollisionEvent.HitTime); case ColliderType.Spinner: - return Colliders.GetSpinnerCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, + return Colliders.Spinner(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime); case ColliderType.Triangle: - return Colliders.GetTriangleCollider(colliderId).HitTest(ref collEvent, in state.InsideOfs, in ball, + return Colliders.Triangle(colliderId).HitTest(ref collEvent, in state.InsideOfs, in ball, ball.CollisionEvent.HitTime); case ColliderType.KickerCircle: case ColliderType.TriggerCircle: - return Colliders.GetCircleCollider(colliderId).HitTestBasicRadius(ref collEvent, ref state.InsideOfs, in ball, + return Colliders.Circle(colliderId).HitTestBasicRadius(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime, false, false, false); case ColliderType.TriggerLine: - return Colliders.GetLineCollider(colliderId).HitTestBasic(ref collEvent, ref state.InsideOfs, in ball, + return Colliders.Line(colliderId).HitTestBasic(ref collEvent, ref state.InsideOfs, in ball, ball.CollisionEvent.HitTime, false, false, false); case ColliderType.Flipper: ref var flipperState = ref state.GetFlipperState(colliderId); - return Colliders.GetFlipperCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, ref flipperState.Hit, + return Colliders.Flipper(colliderId).HitTest(ref collEvent, ref state.InsideOfs, ref flipperState.Hit, in flipperState.Movement, in flipperState.Tricks, in flipperState.Static, in ball, collEvent.HitTime); case ColliderType.Plunger: ref var plungerState = ref state.GetPlungerState(colliderId); - return Colliders.GetPlungerCollider(colliderId).HitTest(ref collEvent, ref state.InsideOfs, ref plungerState.Movement, + return Colliders.Plunger(colliderId).HitTest(ref collEvent, ref state.InsideOfs, ref plungerState.Movement, in plungerState.Collider, in plungerState.Static, in ball, collEvent.HitTime); } return -1f; @@ -224,8 +173,7 @@ internal float HitTest(int colliderId, ref BallState ball, ref CollisionEventDat private bool IsInactiveDropTarget(int colliderId) { - ref var coll = ref Colliders.Value.Colliders[colliderId].Value; - if (coll.ItemType == ItemType.HitTarget && HasDropTargetState(colliderId)) { + if (Colliders.GetItemType(colliderId) == ItemType.HitTarget && HasDropTargetState(colliderId)) { ref var dropTargetState = ref GetDropTargetState(colliderId); if (dropTargetState.Animation.IsDropped || dropTargetState.Animation.MoveAnimation) { // QUICKFIX so that DT is not triggered twice return true; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index ba57c28b7..24b4f6ddb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -48,32 +48,32 @@ private static void Collide(ref BallState ball, ref PhysicsState state) switch (state.Colliders.GetType(colliderId)) { case ColliderType.Circle: - ref var circleCollider = ref state.Colliders.GetCircleCollider(colliderId); + ref var circleCollider = ref state.Colliders.Circle(colliderId); circleCollider.Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Plane: - ref var planeCollider = ref state.Colliders.GetPlaneCollider(colliderId); + ref var planeCollider = ref state.Colliders.Plane(colliderId); planeCollider.Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Line: - ref var lineCollider = ref state.Colliders.GetLineCollider(colliderId); + ref var lineCollider = ref state.Colliders.Line(colliderId); lineCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Triangle: - ref var triangleCollider = ref state.Colliders.GetTriangleCollider(colliderId); + ref var triangleCollider = ref state.Colliders.Triangle(colliderId); triangleCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Line3D: - ref var line3DCollider = ref state.Colliders.GetLine3DCollider(colliderId); + ref var line3DCollider = ref state.Colliders.Line3D(colliderId); line3DCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Point: - ref var pointCollider = ref state.Colliders.GetPointCollider(colliderId); + ref var pointCollider = ref state.Colliders.Point(colliderId); pointCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; @@ -85,7 +85,7 @@ private static void Collide(ref BallState ball, ref PhysicsState state) case ColliderType.Flipper: ref var flipperState = ref state.GetFlipperState(colliderId); - ref var flipperCollider = ref state.Colliders.GetFlipperCollider(colliderId); + ref var flipperCollider = ref state.Colliders.Flipper(colliderId); flipperCollider.Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, ref state.EventQueue, in ball.Id, in flipperState.Tricks, in flipperState.Static, in flipperState.Velocity, in flipperState.Hit, state.Env.TimeMsec @@ -100,7 +100,7 @@ private static void Collide(ref BallState ball, ref PhysicsState state) case ColliderType.LineSlingShot: ref var surfaceState = ref state.GetSurfaceState(colliderId); - ref var surfaceCollider = ref state.Colliders.GetLineSlingshotCollider(colliderId); + ref var surfaceCollider = ref state.Colliders.LineSlingShot(colliderId); surfaceCollider.Collide(ref ball, ref state.EventQueue, in surfaceState.Slingshot, in ball.CollisionEvent, ref state.Env.Random); break; @@ -135,7 +135,7 @@ private static bool CollidesWithItem(ref ColliderHeader collHeader, ref BallStat if (collHeader.ItemType == ItemType.HitTarget) { var normal = collHeader.Type == ColliderType.Triangle - ? state.Colliders.GetTriangleCollider(colliderId).Normal() + ? state.Colliders.Triangle(colliderId).Normal() : ball.CollisionEvent.HitNormal; if (state.HasDropTargetState(colliderId)) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs index e1e28fa8e..45230352d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs @@ -34,7 +34,7 @@ internal struct PhysicsUpdateJob : IJob public NativeParallelHashSet OverlappingColliders; public NativeArray PhysicsEnv; public NativeOctree Octree; - public BlobAssetReference Colliders; + public NativeColliders Colliders; public InsideOfs InsideOfs; public NativeQueue.ParallelWriter Events; public AABB PlayfieldBounds; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs index 37b31282c..9d4effcce 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs @@ -201,16 +201,51 @@ internal void Add(PlaneCollider collider) #endregion - public readonly struct ColliderLookup - { - public readonly ColliderType Type; - public readonly int Index; - - public ColliderLookup(ColliderType type, int index) - { - Type = type; - Index = index; + public ICollider[] ToArray() + { + var array = new ICollider[Lookup.Length]; + for (var i = 0; i < Lookup.Length; i++) { + var lookup = Lookup[i]; + switch (lookup.Type) { + case ColliderType.Circle: + array[i] = CircleColliders[lookup.Index]; + break; + case ColliderType.Flipper: + array[i] = FlipperColliders[lookup.Index]; + break; + case ColliderType.Gate: + array[i] = GateColliders[lookup.Index]; + break; + case ColliderType.Line3D: + array[i] = Line3DColliders[lookup.Index]; + break; + case ColliderType.LineSlingShot: + array[i] = LineSlingshotColliders[lookup.Index]; + break; + case ColliderType.Line: + array[i] = LineColliders[lookup.Index]; + break; + case ColliderType.LineZ: + array[i] = LineZColliders[lookup.Index]; + break; + case ColliderType.Plunger: + array[i] = PlungerColliders[lookup.Index]; + break; + case ColliderType.Point: + array[i] = PointColliders[lookup.Index]; + break; + case ColliderType.Spinner: + array[i] = SpinnerColliders[lookup.Index]; + break; + case ColliderType.Triangle: + array[i] = TriangleColliders[lookup.Index]; + break; + case ColliderType.Plane: + array[i] = PlaneColliders[lookup.Index]; + break; + } } + return array; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs index 5219f716d..a22649070 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs @@ -133,5 +133,7 @@ public void Collide(ref BallState ball, ref NativeQueue.ParallelWrite Collider.FireHitEvent(ref ball, ref hitEvents, in Header); } } + + public override string ToString() => $"Line3DCollider[{Header.ItemId}] ({_xy.x}/{_xy.y} | {_zLow} -> {_zHigh})"; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs index 6014efdc9..17be1d90a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs @@ -146,5 +146,7 @@ public void Collide(ref BallState ball, ref NativeQueue.ParallelWrit } #endregion + + public override string ToString() => $"PointCollider[{Header.ItemId}] ({P.x}/{P.y}/{P.z})"; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs index 452748854..f1523ccac 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactPhysics.cs @@ -24,7 +24,7 @@ internal static void Update(ref ContactBufferElement contact, ref BallState ball if (collEvent.ColliderId > -1) { // collide with static collider var collHeader = state.GetColliderHeader(collEvent.ColliderId); if (collHeader.Type == ColliderType.Flipper) { - ref var flipperCollider = ref state.Colliders.GetFlipperCollider(collEvent.ColliderId); + ref var flipperCollider = ref state.Colliders.Flipper(collEvent.ColliderId); ref var flipperState = ref state.GetFlipperState(collEvent.ColliderId); flipperCollider.Contact(ref ball, ref flipperState.Movement, in collEvent, in flipperState.Static, in flipperState.Velocity, hitTime, in state.Env.Gravity); @@ -32,7 +32,8 @@ internal static void Update(ref ContactBufferElement contact, ref BallState ball Collider.Contact(in collHeader, ref ball, in collEvent, hitTime, in state.Env.Gravity); } } else if (collEvent.BallId != 0) { // collide with ball - BallCollider.HandleStaticContact(ref ball, in collEvent, state.Colliders.GetFriction(contact.CollEvent.ColliderId), hitTime, state.Env.Gravity); + ref var collHeader = ref state.GetColliderHeader(contact.CollEvent.ColliderId); + BallCollider.HandleStaticContact(ref ball, in collEvent, collHeader.Material.Friction, hitTime, state.Env.Gravity); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs new file mode 100644 index 000000000..8272db965 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs @@ -0,0 +1,630 @@ +// Visual Pinball Engine +// Copyright (C) 2023 freezy and VPE Team +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// ReSharper disable InconsistentNaming + +using System.Diagnostics; +using System; +using Unity.Burst; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Collections; +using Unity.Profiling; +using VisualPinball.Engine.VPT; + +namespace VisualPinball.Unity +{ + [NativeContainer] + [NativeContainerSupportsMinMaxWriteRestriction] + [DebuggerDisplay("Length = {Length}")] + [DebuggerTypeProxy(typeof(NativeCollidersDebugView))] + public unsafe struct NativeColliders : IDisposable + { + #region Members + + private static readonly ProfilerMarker PerfMarker = new("NativeColliders Allocation"); + + public int Length => m_Length; + + /// + /// An array that links the collider IDs (the key) to the position in the respective collider buffer. + /// + [NativeDisableUnsafePtrRestriction] private void* m_LookupBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_CircleColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_FlipperColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_GateColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_Line3DColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_LineSlingshotColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_LineColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_LineZColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_PlungerColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_PointColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_SpinnerColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_TriangleColliderBuffer; + [NativeDisableUnsafePtrRestriction] private void* m_PlaneColliderBuffer; + + private readonly Allocator m_AllocatorLabel; + + private int m_Length; // must be here, and called like that. + +#if ENABLE_UNITY_COLLECTIONS_CHECKS + internal int m_MinIndex; + internal int m_MaxIndex; + internal AtomicSafetyHandle m_Safety; + internal static readonly SharedStatic s_staticSafetyId = SharedStatic.GetOrCreate(); +#endif + + #endregion + + #region Constructor / Allocation + + public NativeColliders(ref ColliderReference colRef, Allocator allocator) + { +#if ENABLE_UNITY_COLLECTIONS_CHECKS + // Native allocation is only valid for Temp, Job and Persistent + if (allocator <= Allocator.None) { + throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); + } +#endif + PerfMarker.Begin(); + + m_Length = colRef.Lookup.Length; + + long size = UnsafeUtility.SizeOf() * colRef.Lookup.Length; + m_LookupBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_LookupBuffer, colRef.Lookup.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.FlipperColliders.Length; + m_FlipperColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_FlipperColliderBuffer, colRef.FlipperColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.CircleColliders.Length; + m_CircleColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_CircleColliderBuffer, colRef.CircleColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.GateColliders.Length; + m_GateColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_GateColliderBuffer, colRef.GateColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.Line3DColliders.Length; + m_Line3DColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_Line3DColliderBuffer, colRef.Line3DColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.LineSlingshotColliders.Length; + m_LineSlingshotColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_LineSlingshotColliderBuffer, colRef.LineSlingshotColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.LineColliders.Length; + m_LineColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_LineColliderBuffer, colRef.LineColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.LineZColliders.Length; + m_LineZColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_LineZColliderBuffer, colRef.LineZColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.PlungerColliders.Length; + m_PlungerColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_PlungerColliderBuffer, colRef.PlungerColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.PointColliders.Length; + m_PointColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_PointColliderBuffer, colRef.PointColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.SpinnerColliders.Length; + m_SpinnerColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_SpinnerColliderBuffer, colRef.SpinnerColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.TriangleColliders.Length; + m_TriangleColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_TriangleColliderBuffer, colRef.TriangleColliders.GetUnsafePtr(), size); + + size = UnsafeUtility.SizeOf() * colRef.PlaneColliders.Length; + m_PlaneColliderBuffer = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(m_PlaneColliderBuffer, colRef.PlaneColliders.GetUnsafePtr(), size); + + m_AllocatorLabel = allocator; + + PerfMarker.End(); + +#if ENABLE_UNITY_COLLECTIONS_CHECKS + m_MinIndex = 0; + m_MaxIndex = m_Length - 1; + m_Safety = CollectionHelper.CreateSafetyHandle(allocator); + CollectionHelper.SetStaticSafetyId(ref m_Safety, ref s_staticSafetyId.Data); +#endif + } + + #endregion + + #region Collider Access + + internal ref CircleCollider Circle(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.Circle) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up circle collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_CircleColliderBuffer, lookup.Index); + } + + internal ref FlipperCollider Flipper(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.Flipper) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up flipper collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_FlipperColliderBuffer, lookup.Index); + } + + internal ref GateCollider Gate(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.Gate) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up gate collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_GateColliderBuffer, lookup.Index); + } + + internal ref Line3DCollider Line3D(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.Line3D) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up line3d collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_Line3DColliderBuffer, lookup.Index); + } + + internal ref LineCollider Line(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.Line) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up line collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_LineColliderBuffer, lookup.Index); + } + + internal ref LineSlingshotCollider LineSlingShot(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.LineSlingShot) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up line slingshot collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_LineSlingshotColliderBuffer, lookup.Index); + } + + internal ref LineZCollider LineZ(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.LineZ) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up line-z collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_LineZColliderBuffer, lookup.Index); + } + + internal ref PlaneCollider Plane(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.Plane) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up plane collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_PlaneColliderBuffer, lookup.Index); + } + + internal ref PlungerCollider Plunger(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.Plunger) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up plunger collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_PlungerColliderBuffer, lookup.Index); + } + + internal ref PointCollider Point(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.Point) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up point collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_PointColliderBuffer, lookup.Index); + } + + internal ref SpinnerCollider Spinner(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.Spinner) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up spinner collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_SpinnerColliderBuffer, lookup.Index); + } + + internal ref TriangleCollider Triangle(int index) + { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); +#if ENABLE_UNITY_COLLECTIONS_CHECKS + if (lookup.Type != ColliderType.Triangle) { + throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up triangle collider."); + } +#endif + return ref UnsafeUtility.ArrayElementAsRef(m_TriangleColliderBuffer, lookup.Index); + } + + #endregion + + #region Collection Access + + public ICollider this[int index] + { + get + { +#if ENABLE_UNITY_COLLECTIONS_CHECKS + // If the container is currently not allowed to read from the buffer + // then this will throw an exception. + // This handles all cases, from already disposed containers + // to safe multithreaded access. + AtomicSafetyHandle.CheckReadAndThrow(m_Safety); + + // Perform out of range checks based on + // the NativeContainerSupportsMinMaxWriteRestriction policy + if (index < m_MinIndex || index > m_MaxIndex) + FailOutOfRangeError(index); +#endif + if (index < 0 || index >= m_Length) { + throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); + } + + var lookup = UnsafeUtility.ReadArrayElement(m_LookupBuffer, index); + switch (lookup.Type) { + case ColliderType.Circle: return UnsafeUtility.ReadArrayElement(m_CircleColliderBuffer, lookup.Index); + case ColliderType.Flipper: return UnsafeUtility.ReadArrayElement(m_FlipperColliderBuffer, lookup.Index); + case ColliderType.Gate: return UnsafeUtility.ReadArrayElement(m_GateColliderBuffer, lookup.Index); + case ColliderType.Line3D: return UnsafeUtility.ReadArrayElement(m_Line3DColliderBuffer, lookup.Index); + case ColliderType.LineSlingShot: return UnsafeUtility.ReadArrayElement(m_LineSlingshotColliderBuffer, lookup.Index); + case ColliderType.Line: return UnsafeUtility.ReadArrayElement(m_LineColliderBuffer, lookup.Index); + case ColliderType.LineZ: return UnsafeUtility.ReadArrayElement(m_LineZColliderBuffer, lookup.Index); + case ColliderType.Plunger: return UnsafeUtility.ReadArrayElement(m_PlungerColliderBuffer, lookup.Index); + case ColliderType.Point: return UnsafeUtility.ReadArrayElement(m_PointColliderBuffer, lookup.Index); + case ColliderType.Spinner: return UnsafeUtility.ReadArrayElement(m_SpinnerColliderBuffer, lookup.Index); + case ColliderType.Triangle: return UnsafeUtility.ReadArrayElement(m_TriangleColliderBuffer, lookup.Index); + case ColliderType.Plane: return UnsafeUtility.ReadArrayElement(m_PlaneColliderBuffer, lookup.Index); + } + throw new ArgumentException($"Unknown lookup type."); + } + + set + { +#if ENABLE_UNITY_COLLECTIONS_CHECKS + // If the container is currently not allowed to write to the buffer + // then this will throw an exception. + // This handles all cases, from already disposed containers + // to safe multithreaded access. + AtomicSafetyHandle.CheckWriteAndThrow(m_Safety); + + // Perform out of range checks based on + // the NativeContainerSupportsMinMaxWriteRestriction policy + if (index < m_MinIndex || index > m_MaxIndex) + FailOutOfRangeError(index); +#endif + + if (index < 0 || index >= m_Length) { + throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); + } + + var lookup = UnsafeUtility.ReadArrayElement(m_LookupBuffer, index); + switch (lookup.Type) { + case ColliderType.Circle: + UnsafeUtility.WriteArrayElement(m_CircleColliderBuffer, lookup.Index, (CircleCollider)value); + break; + case ColliderType.Flipper: + UnsafeUtility.WriteArrayElement(m_FlipperColliderBuffer, lookup.Index, (FlipperCollider)value); + break; + case ColliderType.Gate: + UnsafeUtility.WriteArrayElement(m_GateColliderBuffer, lookup.Index, (GateCollider)value); + break; + case ColliderType.Line: + UnsafeUtility.WriteArrayElement(m_LineColliderBuffer, lookup.Index, (LineCollider)value); + break; + case ColliderType.Line3D: + UnsafeUtility.WriteArrayElement(m_Line3DColliderBuffer, lookup.Index, (Line3DCollider)value); + break; + case ColliderType.LineSlingShot: + UnsafeUtility.WriteArrayElement(m_LineSlingshotColliderBuffer, lookup.Index, (LineSlingshotCollider)value); + break; + case ColliderType.LineZ: + UnsafeUtility.WriteArrayElement(m_LineZColliderBuffer, lookup.Index, (LineZCollider)value); + break; + case ColliderType.Plane: + UnsafeUtility.WriteArrayElement(m_PlaneColliderBuffer, lookup.Index, (PlaneCollider)value); + break; + case ColliderType.Plunger: + UnsafeUtility.WriteArrayElement(m_PlungerColliderBuffer, lookup.Index, (PlungerCollider)value); + break; + case ColliderType.Point: + UnsafeUtility.WriteArrayElement(m_PointColliderBuffer, lookup.Index, (PointCollider)value); + break; + case ColliderType.Spinner: + UnsafeUtility.WriteArrayElement(m_SpinnerColliderBuffer, lookup.Index, (SpinnerCollider)value); + break; + case ColliderType.Triangle: + UnsafeUtility.WriteArrayElement(m_TriangleColliderBuffer, lookup.Index, (TriangleCollider)value); + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } + + #endregion + + #region Disposition + + public void Dispose() + { +#if ENABLE_UNITY_COLLECTIONS_CHECKS + CollectionHelper.DisposeSafetyHandle(ref m_Safety); +#endif + + UnsafeUtility.Free(m_LookupBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_CircleColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_FlipperColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_GateColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_Line3DColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_LineSlingshotColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_LineColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_LineZColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_PlungerColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_PointColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_SpinnerColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_TriangleColliderBuffer, m_AllocatorLabel); + UnsafeUtility.Free(m_PlaneColliderBuffer, m_AllocatorLabel); + + m_LookupBuffer = null; + m_CircleColliderBuffer = null; + m_FlipperColliderBuffer = null; + m_GateColliderBuffer = null; + m_Line3DColliderBuffer = null; + m_LineSlingshotColliderBuffer = null; + m_LineColliderBuffer = null; + m_LineZColliderBuffer = null; + m_PlungerColliderBuffer = null; + m_PointColliderBuffer = null; + m_SpinnerColliderBuffer = null; + m_TriangleColliderBuffer = null; + m_PlaneColliderBuffer = null; + m_Length = 0; + } + +#if ENABLE_UNITY_COLLECTIONS_CHECKS + private void FailOutOfRangeError(int index) + { + if (index < Length && (m_MinIndex != 0 || m_MaxIndex != Length - 1)) + throw new IndexOutOfRangeException(string.Format( + "Index {0} is out of restricted IJobParallelFor range [{1}...{2}] in ReadWriteBuffer.\n" + + "ReadWriteBuffers are restricted to only read & write the element at the job index. " + + "You can use double buffering strategies to avoid race conditions due to " + + "reading & writing in parallel to the same elements from a job.", + index, m_MinIndex, m_MaxIndex)); + + throw new IndexOutOfRangeException($"Index {index} is out of range of '{Length}' Length."); + } +#endif + + #endregion + + #region Collider Data + + public ColliderType GetType(int index) + { + if (index < 0 || index >= m_Length) { + throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); + } + var lookup = UnsafeUtility.ReadArrayElement(m_LookupBuffer, index); + return lookup.Type; + } + + public Aabb GetAabb(int index) + { + if (index < 0 || index >= m_Length) { + throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); + } + var lookup = UnsafeUtility.ReadArrayElement(m_LookupBuffer, index); + switch (lookup.Type) { + case ColliderType.Circle: return UnsafeUtility.ArrayElementAsRef(m_CircleColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.Flipper: return UnsafeUtility.ArrayElementAsRef(m_FlipperColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.Gate: return UnsafeUtility.ArrayElementAsRef(m_GateColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.Line3D: return UnsafeUtility.ArrayElementAsRef(m_Line3DColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.LineSlingShot: return UnsafeUtility.ArrayElementAsRef(m_LineSlingshotColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.Line: return UnsafeUtility.ArrayElementAsRef(m_LineColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.LineZ: return UnsafeUtility.ArrayElementAsRef(m_LineZColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.Plunger: return UnsafeUtility.ArrayElementAsRef(m_PlungerColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.Point: return UnsafeUtility.ArrayElementAsRef(m_PointColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.Spinner: return UnsafeUtility.ArrayElementAsRef(m_SpinnerColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.Triangle: return UnsafeUtility.ArrayElementAsRef(m_TriangleColliderBuffer, lookup.Index).Bounds.Aabb; + case ColliderType.Plane: return UnsafeUtility.ArrayElementAsRef(m_PlaneColliderBuffer, lookup.Index).Bounds.Aabb; + } + throw new ArgumentException($"Unknown lookup type."); + } + + public int GetItemId(int index) + { + if (index < 0 || index >= m_Length) { + throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); + } + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + switch (lookup.Type) { + case ColliderType.Circle: return UnsafeUtility.ArrayElementAsRef(m_CircleColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.Flipper: return UnsafeUtility.ArrayElementAsRef(m_FlipperColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.Gate: return UnsafeUtility.ArrayElementAsRef(m_GateColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.Line3D: return UnsafeUtility.ArrayElementAsRef(m_Line3DColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.LineSlingShot: return UnsafeUtility.ArrayElementAsRef(m_LineSlingshotColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.Line: return UnsafeUtility.ArrayElementAsRef(m_LineColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.LineZ: return UnsafeUtility.ArrayElementAsRef(m_LineZColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.Plunger: return UnsafeUtility.ArrayElementAsRef(m_PlungerColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.Point: return UnsafeUtility.ArrayElementAsRef(m_PointColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.Spinner: return UnsafeUtility.ArrayElementAsRef(m_SpinnerColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.Triangle: return UnsafeUtility.ArrayElementAsRef(m_TriangleColliderBuffer, lookup.Index).Header.ItemId; + case ColliderType.Plane: return UnsafeUtility.ArrayElementAsRef(m_PlaneColliderBuffer, lookup.Index).Header.ItemId; + } + throw new ArgumentException($"Unknown lookup type."); + } + + public ItemType GetItemType(int index) + { + if (index < 0 || index >= m_Length) { + throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); + } + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + switch (lookup.Type) { + case ColliderType.Circle: return UnsafeUtility.ArrayElementAsRef(m_CircleColliderBuffer, lookup.Index).Header.ItemType; + case ColliderType.Flipper: return UnsafeUtility.ArrayElementAsRef(m_FlipperColliderBuffer, lookup.Index).Header.ItemType; + case ColliderType.Gate: return UnsafeUtility.ArrayElementAsRef(m_GateColliderBuffer, lookup.Index).Header.ItemType; + case ColliderType.Line3D: return UnsafeUtility.ArrayElementAsRef(m_Line3DColliderBuffer, lookup.Index).Header.ItemType; + case ColliderType.LineSlingShot: return UnsafeUtility.ArrayElementAsRef(m_LineSlingshotColliderBuffer, lookup.Index).Header.ItemType; + case ColliderType.Line: return UnsafeUtility.ArrayElementAsRef(m_LineColliderBuffer, lookup.Index).ItemType; + case ColliderType.LineZ: return UnsafeUtility.ArrayElementAsRef(m_LineZColliderBuffer, lookup.Index).Header.ItemType; + case ColliderType.Plunger: return UnsafeUtility.ArrayElementAsRef(m_PlungerColliderBuffer, lookup.Index).Header.ItemType; + case ColliderType.Point: return UnsafeUtility.ArrayElementAsRef(m_PointColliderBuffer, lookup.Index).Header.ItemType; + case ColliderType.Spinner: return UnsafeUtility.ArrayElementAsRef(m_SpinnerColliderBuffer, lookup.Index).Header.ItemType; + case ColliderType.Triangle: return UnsafeUtility.ArrayElementAsRef(m_TriangleColliderBuffer, lookup.Index).Header.ItemType; + case ColliderType.Plane: return UnsafeUtility.ArrayElementAsRef(m_PlaneColliderBuffer, lookup.Index).Header.ItemType; + } + throw new ArgumentException($"Unknown lookup type."); + } + + public ref ColliderHeader GetHeader(int index) + { + if (index < 0 || index >= m_Length) { + throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); + } + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + switch (lookup.Type) { + case ColliderType.Circle: return ref UnsafeUtility.ArrayElementAsRef(m_CircleColliderBuffer, lookup.Index).Header; + case ColliderType.Flipper: return ref UnsafeUtility.ArrayElementAsRef(m_FlipperColliderBuffer, lookup.Index).Header; + case ColliderType.Gate: return ref UnsafeUtility.ArrayElementAsRef(m_GateColliderBuffer, lookup.Index).Header; + case ColliderType.Line3D: return ref UnsafeUtility.ArrayElementAsRef(m_Line3DColliderBuffer, lookup.Index).Header; + case ColliderType.LineSlingShot: return ref UnsafeUtility.ArrayElementAsRef(m_LineSlingshotColliderBuffer, lookup.Index).Header; + case ColliderType.Line: return ref UnsafeUtility.ArrayElementAsRef(m_LineColliderBuffer, lookup.Index).Header; + case ColliderType.LineZ: return ref UnsafeUtility.ArrayElementAsRef(m_LineZColliderBuffer, lookup.Index).Header; + case ColliderType.Plunger: return ref UnsafeUtility.ArrayElementAsRef(m_PlungerColliderBuffer, lookup.Index).Header; + case ColliderType.Point: return ref UnsafeUtility.ArrayElementAsRef(m_PointColliderBuffer, lookup.Index).Header; + case ColliderType.Spinner: return ref UnsafeUtility.ArrayElementAsRef(m_SpinnerColliderBuffer, lookup.Index).Header; + case ColliderType.Triangle: return ref UnsafeUtility.ArrayElementAsRef(m_TriangleColliderBuffer, lookup.Index).Header; + case ColliderType.Plane: return ref UnsafeUtility.ArrayElementAsRef(m_PlaneColliderBuffer, lookup.Index).Header; + } + throw new ArgumentException($"Unknown lookup type."); + } + + #endregion + + #region Debug + + public ICollider[] ToArray() + { +#if ENABLE_UNITY_COLLECTIONS_CHECKS + AtomicSafetyHandle.CheckReadAndThrow(m_Safety); +#endif + var array = new ICollider[Length]; + for (var i = 0; i < Length; i++) { + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, i); + switch (lookup.Type) { + case ColliderType.Circle: + array[i] = UnsafeUtility.ReadArrayElement(m_CircleColliderBuffer, lookup.Index); + break; + case ColliderType.Flipper: + array[i] = UnsafeUtility.ReadArrayElement(m_FlipperColliderBuffer, lookup.Index); + break; + case ColliderType.Gate: + array[i] = UnsafeUtility.ReadArrayElement(m_GateColliderBuffer, lookup.Index); + break; + case ColliderType.Line3D: + array[i] = UnsafeUtility.ReadArrayElement(m_Line3DColliderBuffer, lookup.Index); + break; + case ColliderType.LineSlingShot: + array[i] = UnsafeUtility.ReadArrayElement(m_LineSlingshotColliderBuffer, lookup.Index); + break; + case ColliderType.Line: + array[i] = UnsafeUtility.ReadArrayElement(m_LineColliderBuffer, lookup.Index); + break; + case ColliderType.LineZ: + array[i] = UnsafeUtility.ReadArrayElement(m_LineZColliderBuffer, lookup.Index); + break; + case ColliderType.Plunger: + array[i] = UnsafeUtility.ReadArrayElement(m_PlungerColliderBuffer, lookup.Index); + break; + case ColliderType.Point: + array[i] = UnsafeUtility.ReadArrayElement(m_PointColliderBuffer, lookup.Index); + break; + case ColliderType.Spinner: + array[i] = UnsafeUtility.ReadArrayElement(m_SpinnerColliderBuffer, lookup.Index); + break; + case ColliderType.Triangle: + array[i] = UnsafeUtility.ReadArrayElement(m_TriangleColliderBuffer, lookup.Index); + break; + case ColliderType.Plane: + array[i] = UnsafeUtility.ReadArrayElement(m_PlaneColliderBuffer, lookup.Index); + break; + } + } + return array; + } + + #endregion + } + + public readonly struct ColliderLookup + { + public readonly ColliderType Type; + public readonly int Index; + + public ColliderLookup(ColliderType type, int index) + { + Type = type; + Index = index; + } + } + + // Visualizes the colliders in the C# debugger + internal sealed class NativeCollidersDebugView + { + private NativeColliders _nativeColliders; + + public NativeCollidersDebugView(NativeColliders nativeColliders) + { + _nativeColliders = nativeColliders; + } + public ICollider[] Colliders => _nativeColliders.ToArray(); + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs.meta new file mode 100644 index 000000000..e941cb236 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 264d4febde7b4f19955044bba6cbd6d6 +timeCreated: 1698263847 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs index 050920697..e03a448f0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ColliderComponent.cs @@ -161,14 +161,9 @@ private void OnDrawGizmos() var playfieldBounds = GetComponentInChildren().Bounds; var octree = new NativeOctree(playfieldBounds, 32, 10, Allocator.Persistent); - - var allocateColliderJob = new ColliderAllocationJob(ref colliders); - allocateColliderJob.Run(); - var colliderBlob = allocateColliderJob.BlobAsset[0]; - allocateColliderJob.Dispose(); - + var nativeColliders = new NativeColliders(ref colliders, Allocator.TempJob); var populateJob = new PhysicsPopulateJob { - Colliders = colliderBlob, + Colliders = nativeColliders, Octree = octree, }; populateJob.Run(); From 9a02e90f92e17bcb03b254a4dfe768c1eddf47f5 Mon Sep 17 00:00:00 2001 From: freezy Date: Thu, 26 Oct 2023 22:54:10 +0200 Subject: [PATCH 145/159] debug: Name blob asset extensions like native colliders. --- .../Game/PhysicsColliderExtensions.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs index 5028f0f4e..166345ae6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs @@ -33,7 +33,7 @@ internal static float GetFriction(this BlobAssetReference collider internal static Aabb GetAabb(this BlobAssetReference colliders, int index) => colliders.Value.Colliders[index].Value.Bounds().Aabb; - internal static unsafe ref CircleCollider GetCircleCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref CircleCollider Circle(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -42,7 +42,7 @@ internal static unsafe ref CircleCollider GetCircleCollider(this in BlobAssetRef } } - internal static unsafe ref PlaneCollider GetPlaneCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref PlaneCollider Plane(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -51,7 +51,7 @@ internal static unsafe ref PlaneCollider GetPlaneCollider(this in BlobAssetRefer } } - internal static unsafe ref SpinnerCollider GetSpinnerCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref SpinnerCollider Spinner(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -60,7 +60,7 @@ internal static unsafe ref SpinnerCollider GetSpinnerCollider(this in BlobAssetR } } - internal static unsafe ref GateCollider GetGateCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref GateCollider Gate(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -69,7 +69,7 @@ internal static unsafe ref GateCollider GetGateCollider(this in BlobAssetReferen } } - internal static unsafe ref LineCollider GetLineCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref LineCollider Line(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -78,7 +78,7 @@ internal static unsafe ref LineCollider GetLineCollider(this in BlobAssetReferen } } - internal static unsafe ref TriangleCollider GetTriangleCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref TriangleCollider Triangle(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -87,7 +87,7 @@ internal static unsafe ref TriangleCollider GetTriangleCollider(this in BlobAsse } } - internal static unsafe ref Line3DCollider GetLine3DCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref Line3DCollider Line3D(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -96,7 +96,7 @@ internal static unsafe ref Line3DCollider GetLine3DCollider(this in BlobAssetRef } } - internal static unsafe ref LineSlingshotCollider GetLineSlingshotCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref LineSlingshotCollider LineSlingShot(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -105,7 +105,7 @@ internal static unsafe ref LineSlingshotCollider GetLineSlingshotCollider(this i } } - internal static unsafe ref PointCollider GetPointCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref PointCollider Point(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -114,7 +114,7 @@ internal static unsafe ref PointCollider GetPointCollider(this in BlobAssetRefer } } - internal static unsafe ref LineZCollider GetLineZCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref LineZCollider LineZ(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -123,7 +123,7 @@ internal static unsafe ref LineZCollider GetLineZCollider(this in BlobAssetRefer } } - internal static unsafe ref FlipperCollider GetFlipperCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref FlipperCollider Flipper(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { @@ -132,7 +132,7 @@ internal static unsafe ref FlipperCollider GetFlipperCollider(this in BlobAssetR } } - internal static unsafe ref PlungerCollider GetPlungerCollider(this in BlobAssetReference colliders, int index) + internal static unsafe ref PlungerCollider Plunger(this in BlobAssetReference colliders, int index) { ref var coll = ref colliders.Value.Colliders[index].Value; fixed (Collider* cPtr = &coll) { From 6a17d3412dcc0f92c7c6b884aee8ff6cfb157c09 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 27 Oct 2023 11:35:58 +0200 Subject: [PATCH 146/159] jobs: Add comparison methods to collider header. --- .../VisualPinball.Unity/Physics/Collision/Aabb.cs | 15 +++++++++++++++ .../Physics/Collision/ColliderHeader.cs | 15 +++++++++++++++ .../Physics/Collision/PhysicsMaterialData.cs | 13 +++++++++++++ 3 files changed, 43 insertions(+) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs index 4f284b30e..b856983d6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/Aabb.cs @@ -107,6 +107,21 @@ public static implicit operator NativeTrees.AABB2D(Aabb aabb) return new NativeTrees.AABB2D(new float2(aabb.Min.x, aabb.Min.y), new float2(aabb.Min.x, aabb.Max.y)); } + public static bool operator == (Aabb a, Aabb b) => a.Equals(b); + + public static bool operator != (Aabb a, Aabb b) => !a.Equals(b); + + private bool Equals(Aabb a) + { + return + a.Right == Left && + a.Left == Left && + a.Bottom == Bottom && + a.Top == Top && + a.ZLow == ZLow && + a.ZHigh == ZHigh; + } + public override string ToString() { return $"Aabb {Left} → {Right} | {Top} ↘ {Bottom} | {ZLow} ↑ {ZHigh}"; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs index 101592517..291e26a84 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderHeader.cs @@ -63,5 +63,20 @@ public void Init(ColliderInfo info, ColliderType colliderType) Threshold = info.HitThreshold; FireEvents = info.FireEvents; } + + public static bool operator == (ColliderHeader a, ColliderHeader b) => a.Equals(b); + public static bool operator != (ColliderHeader a, ColliderHeader b) => !a.Equals(b); + + public bool Equals(ColliderHeader other) + { + return + Type == other.Type && + ItemType == other.ItemType && + Id == other.Id && + ItemId == other.ItemId && + Material == other.Material && + Threshold == other.Threshold && + FireEvents == other.FireEvents; + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs index 66c5c74ec..77c3e561d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/PhysicsMaterialData.cs @@ -29,5 +29,18 @@ public struct PhysicsMaterialData public FixedList512Bytes FrictionOverVelocityLUT; public bool UseFrictionOverVelocity; + public static bool operator == (PhysicsMaterialData a, PhysicsMaterialData b) => a.Equals(b); + public static bool operator != (PhysicsMaterialData a, PhysicsMaterialData b) => !a.Equals(b); + + public bool Equals(PhysicsMaterialData other) + { + return + Elasticity == other.Elasticity && + ElasticityFalloff == other.ElasticityFalloff && + Friction == other.Friction && + ScatterAngleRad == other.ScatterAngleRad && + UseElasticityOverVelocity == other.UseElasticityOverVelocity && + UseFrictionOverVelocity == other.UseFrictionOverVelocity; + } } } From 30f0998fdd081f6bcd5eb4f6aa904ce7998b9e8f Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 27 Oct 2023 18:32:40 +0200 Subject: [PATCH 147/159] jobs: Simplify native colliders. --- .../Physics/NativeCollider.cs | 48 ++----------------- 1 file changed, 4 insertions(+), 44 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs index 8272db965..83c1a54f0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs @@ -478,57 +478,17 @@ public Aabb GetAabb(int index) throw new ArgumentException($"Unknown lookup type."); } - public int GetItemId(int index) - { - if (index < 0 || index >= m_Length) { - throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); - } - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); - switch (lookup.Type) { - case ColliderType.Circle: return UnsafeUtility.ArrayElementAsRef(m_CircleColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.Flipper: return UnsafeUtility.ArrayElementAsRef(m_FlipperColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.Gate: return UnsafeUtility.ArrayElementAsRef(m_GateColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.Line3D: return UnsafeUtility.ArrayElementAsRef(m_Line3DColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.LineSlingShot: return UnsafeUtility.ArrayElementAsRef(m_LineSlingshotColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.Line: return UnsafeUtility.ArrayElementAsRef(m_LineColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.LineZ: return UnsafeUtility.ArrayElementAsRef(m_LineZColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.Plunger: return UnsafeUtility.ArrayElementAsRef(m_PlungerColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.Point: return UnsafeUtility.ArrayElementAsRef(m_PointColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.Spinner: return UnsafeUtility.ArrayElementAsRef(m_SpinnerColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.Triangle: return UnsafeUtility.ArrayElementAsRef(m_TriangleColliderBuffer, lookup.Index).Header.ItemId; - case ColliderType.Plane: return UnsafeUtility.ArrayElementAsRef(m_PlaneColliderBuffer, lookup.Index).Header.ItemId; - } - throw new ArgumentException($"Unknown lookup type."); - } + public int GetItemId(int index) => GetHeader(index).ItemId; - public ItemType GetItemType(int index) - { - if (index < 0 || index >= m_Length) { - throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); - } - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); - switch (lookup.Type) { - case ColliderType.Circle: return UnsafeUtility.ArrayElementAsRef(m_CircleColliderBuffer, lookup.Index).Header.ItemType; - case ColliderType.Flipper: return UnsafeUtility.ArrayElementAsRef(m_FlipperColliderBuffer, lookup.Index).Header.ItemType; - case ColliderType.Gate: return UnsafeUtility.ArrayElementAsRef(m_GateColliderBuffer, lookup.Index).Header.ItemType; - case ColliderType.Line3D: return UnsafeUtility.ArrayElementAsRef(m_Line3DColliderBuffer, lookup.Index).Header.ItemType; - case ColliderType.LineSlingShot: return UnsafeUtility.ArrayElementAsRef(m_LineSlingshotColliderBuffer, lookup.Index).Header.ItemType; - case ColliderType.Line: return UnsafeUtility.ArrayElementAsRef(m_LineColliderBuffer, lookup.Index).ItemType; - case ColliderType.LineZ: return UnsafeUtility.ArrayElementAsRef(m_LineZColliderBuffer, lookup.Index).Header.ItemType; - case ColliderType.Plunger: return UnsafeUtility.ArrayElementAsRef(m_PlungerColliderBuffer, lookup.Index).Header.ItemType; - case ColliderType.Point: return UnsafeUtility.ArrayElementAsRef(m_PointColliderBuffer, lookup.Index).Header.ItemType; - case ColliderType.Spinner: return UnsafeUtility.ArrayElementAsRef(m_SpinnerColliderBuffer, lookup.Index).Header.ItemType; - case ColliderType.Triangle: return UnsafeUtility.ArrayElementAsRef(m_TriangleColliderBuffer, lookup.Index).Header.ItemType; - case ColliderType.Plane: return UnsafeUtility.ArrayElementAsRef(m_PlaneColliderBuffer, lookup.Index).Header.ItemType; - } - throw new ArgumentException($"Unknown lookup type."); - } + public ItemType GetItemType(int index) => GetHeader(index).ItemType; public ref ColliderHeader GetHeader(int index) { +#if ENABLE_UNITY_COLLECTIONS_CHECKS if (index < 0 || index >= m_Length) { throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); } +#endif ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); switch (lookup.Type) { case ColliderType.Circle: return ref UnsafeUtility.ArrayElementAsRef(m_CircleColliderBuffer, lookup.Index).Header; From 96deea0f60912412a72341ddb8032150b8ae6b10 Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 27 Oct 2023 18:50:37 +0200 Subject: [PATCH 148/159] refactor: Handle collider ID assignment within collider. --- .../Physics/Collider/CircleCollider.cs | 6 ++- .../Physics/Collider/ColliderReference.cs | 41 ++++++------------- .../Physics/Collider/Line3DCollider.cs | 13 +++++- .../Physics/Collider/LineCollider.cs | 6 ++- .../Physics/Collider/LineSlingshotCollider.cs | 6 ++- .../Physics/Collider/LineZCollider.cs | 6 ++- .../Physics/Collider/PlaneCollider.cs | 8 ++-- .../Physics/Collider/PointCollider.cs | 6 ++- .../Physics/Collider/TriangleCollider.cs | 6 ++- .../VPT/Flipper/FlipperCollider.cs | 11 ++++- .../VPT/Gate/GateCollider.cs | 13 +++++- .../VPT/Plunger/PlungerCollider.cs | 13 +++++- .../VPT/Spinner/SpinnerCollider.cs | 13 +++++- 13 files changed, 102 insertions(+), 46 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs index fc591d44c..bdcda2115 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs @@ -24,7 +24,11 @@ namespace VisualPinball.Unity { internal struct CircleCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set => Header.Id = value; + } public ColliderHeader Header; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs index 9d4effcce..dcd31ce9d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs @@ -80,7 +80,7 @@ private ICollider LookupCollider(int i) throw new IndexOutOfRangeException($"Invalid index {i} when looking up collider."); } - var lookup = Lookup[i]; + ref var lookup = ref Lookup.GetElementAsRef(i); switch (lookup.Type) { case ColliderType.Circle: return CircleColliders.GetElementAsRef(lookup.Index); case ColliderType.Flipper: return FlipperColliders.GetElementAsRef(lookup.Index); @@ -102,99 +102,84 @@ private ICollider LookupCollider(int i) internal void Add(CircleCollider collider) { - collider.Header.Id = Lookup.Length; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Circle, CircleColliders.Length)); CircleColliders.Add(collider); } internal void Add(FlipperCollider collider) { - collider.Header.Id = Lookup.Length; - var bounds = collider.Bounds; - bounds.ColliderId = collider.Header.Id; - collider.Bounds = bounds; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Flipper, FlipperColliders.Length)); FlipperColliders.Add(collider); } internal void Add(GateCollider collider) { - collider.Header.Id = Lookup.Length; - var bounds = collider.Bounds; - bounds.ColliderId = collider.Header.Id; - collider.Bounds = bounds; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Gate, GateColliders.Length)); GateColliders.Add(collider); } internal void Add(Line3DCollider collider) { - collider.Header.Id = Lookup.Length; - var bounds = collider.Bounds; - bounds.ColliderId = collider.Header.Id; - collider.Bounds = bounds; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Line3D, Line3DColliders.Length)); Line3DColliders.Add(collider); } internal void Add(LineSlingshotCollider collider) { - collider.Header.Id = Lookup.Length; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.LineSlingShot, LineSlingshotColliders.Length)); LineSlingshotColliders.Add(collider); } internal void Add(LineCollider collider) { - collider.Header.Id = Lookup.Length; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Line, LineColliders.Length)); LineColliders.Add(collider); } internal void Add(LineZCollider collider) { - collider.Header.Id = Lookup.Length; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.LineZ, LineZColliders.Length)); LineZColliders.Add(collider); } internal void Add(PlungerCollider collider) { - collider.Header.Id = Lookup.Length; - var bounds = collider.Bounds; - bounds.ColliderId = collider.Header.Id; - collider.Bounds = bounds; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Plunger, PlungerColliders.Length)); PlungerColliders.Add(collider); } internal void Add(PointCollider collider) { - collider.Header.Id = Lookup.Length; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Point, PointColliders.Length)); PointColliders.Add(collider); } internal void Add(SpinnerCollider collider) { - collider.Header.Id = Lookup.Length; - var bounds = collider.Bounds; - bounds.ColliderId = collider.Header.Id; - collider.Bounds = bounds; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Spinner, SpinnerColliders.Length)); SpinnerColliders.Add(collider); } internal void Add(TriangleCollider collider) { - collider.Header.Id = Lookup.Length; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Triangle, TriangleColliders.Length)); TriangleColliders.Add(collider); } internal void Add(PlaneCollider collider) { - collider.Header.Id = Lookup.Length; + collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Plane, PlaneColliders.Length)); PlaneColliders.Add(collider); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs index a22649070..467d396d5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs @@ -23,7 +23,16 @@ namespace VisualPinball.Unity { internal struct Line3DCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set { + Header.Id = value; + var bounds = Bounds; + bounds.ColliderId = value; + Bounds = bounds; + } + } public ColliderHeader Header; @@ -37,7 +46,7 @@ internal struct Line3DCollider : ICollider private readonly float _zHigh; private readonly float3x3 _matrix; - public ColliderBounds Bounds { get; set; } + public ColliderBounds Bounds { get; private set; } public Line3DCollider(float3 v1, float3 v2, ColliderInfo info) : this() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index 052015189..8ac6be29d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -25,7 +25,11 @@ namespace VisualPinball.Unity { internal struct LineCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set => Header.Id = value; + } public ColliderHeader Header; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs index ca10b049d..3ff50db19 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs @@ -24,7 +24,11 @@ namespace VisualPinball.Unity { internal struct LineSlingshotCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set => Header.Id = value; + } public ColliderHeader Header; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs index e1c736c52..604923a06 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs @@ -24,7 +24,11 @@ namespace VisualPinball.Unity { internal struct LineZCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set => Header.Id = value; + } public ColliderHeader Header; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index 48874cf52..872195fb6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -25,9 +25,11 @@ namespace VisualPinball.Unity { internal struct PlaneCollider : ICollider { - public int Id => Header.Id; - public PhysicsMaterialData Material => Header.Material; - + public int Id + { + get => Header.Id; + set => Header.Id = value; + } public ColliderHeader Header; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs index 17be1d90a..5b09ccf2a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs @@ -24,7 +24,11 @@ namespace VisualPinball.Unity { internal struct PointCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set => Header.Id = value; + } public ColliderHeader Header; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs index 5880a23af..5bb509378 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs @@ -25,7 +25,11 @@ namespace VisualPinball.Unity { internal struct TriangleCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set => Header.Id = value; + } public ColliderHeader Header; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs index a7dfcd404..e9dfa6d00 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs @@ -26,7 +26,16 @@ namespace VisualPinball.Unity { internal struct FlipperCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set { + Header.Id = value; + var bounds = Bounds; + bounds.ColliderId = value; + Bounds = bounds; + } + } public ColliderHeader Header; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs index f0419345d..f522039f6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs @@ -23,14 +23,23 @@ namespace VisualPinball.Unity { internal struct GateCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set { + Header.Id = value; + var bounds = Bounds; + bounds.ColliderId = value; + Bounds = bounds; + } + } public ColliderHeader Header; public readonly LineCollider LineSeg0; public readonly LineCollider LineSeg1; - public ColliderBounds Bounds { get; set; } + public ColliderBounds Bounds { get; private set; } public GateCollider(in LineCollider lineSeg0, in LineCollider lineSeg1, ColliderInfo info) : this() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs index dfe37cb51..6d45277d5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs @@ -25,7 +25,16 @@ namespace VisualPinball.Unity { internal struct PlungerCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set { + Header.Id = value; + var bounds = Bounds; + bounds.ColliderId = value; + Bounds = bounds; + } + } public ColliderHeader Header; @@ -33,7 +42,7 @@ internal struct PlungerCollider : ICollider public LineZCollider JointBase0; public LineZCollider JointBase1; - public ColliderBounds Bounds { get; set; } + public ColliderBounds Bounds { get; private set; } public PlungerCollider(PlungerComponent comp, PlungerColliderComponent collComp, ColliderInfo info) : this() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs index 722f87ef4..e9bea4d0d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs @@ -24,14 +24,23 @@ namespace VisualPinball.Unity { internal struct SpinnerCollider : ICollider { - public int Id => Header.Id; + public int Id + { + get => Header.Id; + set { + Header.Id = value; + var bounds = Bounds; + bounds.ColliderId = value; + Bounds = bounds; + } + } public ColliderHeader Header; public readonly LineCollider LineSeg0; public readonly LineCollider LineSeg1; - public ColliderBounds Bounds { get; set; } + public ColliderBounds Bounds { get; private set; } public SpinnerCollider(SpinnerComponent component, float height, ColliderInfo info) : this() { From fd7edf1842e80b0b5411f6582ee4e913ec8057cd Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 27 Oct 2023 19:09:07 +0200 Subject: [PATCH 149/159] jobs: Fix ball fall-through. --- .../VisualPinball.Unity/Game/PhysicsState.cs | 4 ++-- .../Game/PhysicsStaticCollision.cs | 24 ++++++++++--------- .../Physics/NativeCollider.cs | 9 ------- 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 393af76de..996d8072f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -16,7 +16,6 @@ using NativeTrees; using Unity.Collections; -using Unity.Entities; using VisualPinball.Engine.VPT; using VisualPinball.Unity.Collections; @@ -73,6 +72,7 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree octree, ref Native } internal ref ColliderHeader GetColliderHeader(int colliderId) => ref Colliders.GetHeader(colliderId); + internal ColliderType GetColliderType(int colliderId) => Colliders.GetHeader(colliderId).Type; internal bool IsColliderActive(int colliderId) => !DisabledCollisionItems.Contains(Colliders.GetItemId(colliderId)); @@ -112,7 +112,7 @@ internal float HitTest(int colliderId, ref BallState ball, ref CollisionEventDat if (IsInactiveDropTarget(colliderId)) { return -1f; } - switch (Colliders.GetType(colliderId)) { + switch (GetColliderType(colliderId)) { case ColliderType.Bumper: case ColliderType.Circle: return Colliders.Circle(colliderId).HitTest(ref collEvent, ref state.InsideOfs, in ball, diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index 24b4f6ddb..a04554bc7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -44,36 +44,36 @@ private static void Collide(ref BallState ball, ref PhysicsState state) if (CollidesWithItem(ref collHeader, ref ball, ref state)) { return; } - - switch (state.Colliders.GetType(colliderId)) { + ref var cols = ref state.Colliders; + switch (state.GetColliderType(colliderId)) { case ColliderType.Circle: - ref var circleCollider = ref state.Colliders.Circle(colliderId); + ref var circleCollider = ref cols.Circle(colliderId); circleCollider.Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Plane: - ref var planeCollider = ref state.Colliders.Plane(colliderId); + ref var planeCollider = ref cols.Plane(colliderId); planeCollider.Collide(ref ball, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Line: - ref var lineCollider = ref state.Colliders.Line(colliderId); + ref var lineCollider = ref cols.Line(colliderId); lineCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Triangle: - ref var triangleCollider = ref state.Colliders.Triangle(colliderId); + ref var triangleCollider = ref cols.Triangle(colliderId); triangleCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Line3D: - ref var line3DCollider = ref state.Colliders.Line3D(colliderId); + ref var line3DCollider = ref cols.Line3D(colliderId); line3DCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; case ColliderType.Point: - ref var pointCollider = ref state.Colliders.Point(colliderId); + ref var pointCollider = ref cols.Point(colliderId); pointCollider.Collide(ref ball, ref state.EventQueue, in ball.CollisionEvent, ref state.Env.Random); break; @@ -85,7 +85,7 @@ private static void Collide(ref BallState ball, ref PhysicsState state) case ColliderType.Flipper: ref var flipperState = ref state.GetFlipperState(colliderId); - ref var flipperCollider = ref state.Colliders.Flipper(colliderId); + ref var flipperCollider = ref cols.Flipper(colliderId); flipperCollider.Collide(ref ball, ref ball.CollisionEvent, ref flipperState.Movement, ref state.EventQueue, in ball.Id, in flipperState.Tricks, in flipperState.Static, in flipperState.Velocity, in flipperState.Hit, state.Env.TimeMsec @@ -100,7 +100,7 @@ private static void Collide(ref BallState ball, ref PhysicsState state) case ColliderType.LineSlingShot: ref var surfaceState = ref state.GetSurfaceState(colliderId); - ref var surfaceCollider = ref state.Colliders.LineSlingShot(colliderId); + ref var surfaceCollider = ref cols.LineSlingShot(colliderId); surfaceCollider.Collide(ref ball, ref state.EventQueue, in surfaceState.Slingshot, in ball.CollisionEvent, ref state.Env.Random); break; @@ -130,12 +130,14 @@ private static void Collide(ref BallState ball, ref PhysicsState state) private static bool CollidesWithItem(ref ColliderHeader collHeader, ref BallState ball, ref PhysicsState state) { + ref var cols = ref state.Colliders; + // hit target var colliderId = ball.CollisionEvent.ColliderId; if (collHeader.ItemType == ItemType.HitTarget) { var normal = collHeader.Type == ColliderType.Triangle - ? state.Colliders.Triangle(colliderId).Normal() + ? cols.Triangle(colliderId).Normal() : ball.CollisionEvent.HitNormal; if (state.HasDropTargetState(colliderId)) { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs index 83c1a54f0..478c3ac3e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs @@ -446,15 +446,6 @@ private void FailOutOfRangeError(int index) #region Collider Data - public ColliderType GetType(int index) - { - if (index < 0 || index >= m_Length) { - throw new IndexOutOfRangeException($"Invalid index {index} when looking up collider."); - } - var lookup = UnsafeUtility.ReadArrayElement(m_LookupBuffer, index); - return lookup.Type; - } - public Aabb GetAabb(int index) { if (index < 0 || index >= m_Length) { From ed6ac3e4a1294d0697e08c03689cc304a93ca53e Mon Sep 17 00:00:00 2001 From: freezy Date: Fri, 27 Oct 2023 22:48:34 +0200 Subject: [PATCH 150/159] project: Disable unit tests. --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a075abe11..f9669cf0e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,6 +49,7 @@ jobs: name: Unit Test needs: [ build ] runs-on: ubuntu-latest + if: false steps: - uses: actions/checkout@v3 - uses: actions/download-artifact@v3 From 263e4d8216239e30182ffcd795e265c2296c7139 Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 28 Oct 2023 11:36:54 +0200 Subject: [PATCH 151/159] project: Disable unit tests (2nd try). --- .github/workflows/build.yml | 63 ++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f9669cf0e..2fe646e43 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,17 +45,16 @@ jobs: name: Plugins path: tmp - test: - name: Unit Test - needs: [ build ] - runs-on: ubuntu-latest - if: false - steps: - - uses: actions/checkout@v3 - - uses: actions/download-artifact@v3 - with: - name: Plugins - path: VisualPinball.Unity/Plugins +# test: +# name: Unit Test +# needs: [ build ] +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v3 +# - uses: actions/download-artifact@v3 +# with: +# name: Plugins +# path: VisualPinball.Unity/Plugins #- uses: actions/cache@v3 # with: # path: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/Library @@ -63,31 +62,31 @@ jobs: # restore-keys: | # Library-Test-Project # Library - - uses: game-ci/unity-test-runner@main - id: test - with: - #unityVersion: "2022.3.10f1" - projectPath: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~ - artifactsPath: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/artifacts - testMode: all - customParameters: -debugCodeOptimization -enableCodeCoverage -burst-disable-compilation -coverageOptions enableCyclomaticComplexity;assemblyFilters:+VisualPinball.Engine;pathFilters:-**/VisualPinball.Engine/Math/Triangulator/**,-**/VisualPinball.Engine/Math/Mesh/** -coverageResultsPath artifacts - - run: | - curl -s https://codecov.io/bash | bash -s - -f ${{ steps.test.outputs.artifactsPath }}/TestProject~-opencov/EditMode/TestCoverageResults_0000.xml - - uses: MirrorNG/nunit-reporter@v1.1.0 - if: always() - with: - path: ${{ steps.test.outputs.artifactsPath }}/*.xml - access-token: ${{ secrets.GITHUB_TOKEN }} - - uses: actions/upload-artifact@v3 - if: always() - with: - name: Test results - path: ${{ steps.test.outputs.artifactsPath }} +# - uses: game-ci/unity-test-runner@main +# id: test +# with: +# #unityVersion: "2022.3.10f1" +# projectPath: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~ +# artifactsPath: VisualPinball.Unity/VisualPinball.Unity.Test/TestProject~/artifacts +# testMode: all +# customParameters: -debugCodeOptimization -enableCodeCoverage -burst-disable-compilation -coverageOptions enableCyclomaticComplexity;assemblyFilters:+VisualPinball.Engine;pathFilters:-**/VisualPinball.Engine/Math/Triangulator/**,-**/VisualPinball.Engine/Math/Mesh/** -coverageResultsPath artifacts +# - run: | +# curl -s https://codecov.io/bash | bash -s - -f ${{ steps.test.outputs.artifactsPath }}/TestProject~-opencov/EditMode/TestCoverageResults_0000.xml +# - uses: MirrorNG/nunit-reporter@v1.1.0 +# if: always() +# with: +# path: ${{ steps.test.outputs.artifactsPath }}/*.xml +# access-token: ${{ secrets.GITHUB_TOKEN }} +# - uses: actions/upload-artifact@v3 +# if: always() +# with: +# name: Test results +# path: ${{ steps.test.outputs.artifactsPath }} dispatch: name: Dispatch runs-on: ubuntu-latest - needs: [ test ] + needs: [ build ] if: github.repository == 'freezy/VisualPinball.Engine' && github.ref == 'refs/heads/master' steps: - uses: peter-evans/repository-dispatch@v1 From 7fec29a95c43b3416a9164182b6f5e7fcbf076cc Mon Sep 17 00:00:00 2001 From: freezy Date: Sat, 28 Oct 2023 11:37:09 +0200 Subject: [PATCH 152/159] doc: Update overview. --- .../creators-guide/introduction/overview.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/VisualPinball.Unity/Documentation~/creators-guide/introduction/overview.md b/VisualPinball.Unity/Documentation~/creators-guide/introduction/overview.md index 358160409..46e9a9ef6 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/introduction/overview.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/introduction/overview.md @@ -7,22 +7,16 @@ description: VPE, the Visual Pinball Engine, is a modern, open source pinball si # Overview -The Visual Pinball Engine (which we call "VPE") is an open source pinball simulator that you can use to create pinball games for Windows, macOS, and Linux. It's based on the famous [Visual Pinball](https://sourceforge.net/projects/vpinball/) (often abbreviated "VP", or "VPX" for its latest version 10) meaning VPE's physics simulation matches that in VPX, and it can read and write the same file format. +The Visual Pinball Engine (which we call "VPE") is an open-source pinball simulator that you can use to create pinball games for Windows, macOS, and Linux. It's based on the famous [Visual Pinball](https://github.com/vpinball/vpinball) (often abbreviated "VP" or "VPX" for its latest version 10), meaning VPE's physics simulation matches that in VPX, and it can read and write the same file format. -VPE uses [Unity](https://unity.com/) for its underlying game architecture. Unity is one of the leading cross-platform game engines and provides VPE with an advanced render pipeline that produces high-quality visuals and is continuously maintained and updated to work with new hardware features. Unity also comes with an amazing editor, which VPE extends to make the table creation process as easy as possible. +VPE uses [Unity](https://unity.com/) for its underlying game architecture. Unity is one of the leading cross-platform game engines and provides VPE with an advanced render pipeline that produces high-quality visuals and is continuously maintained and updated to work with new hardware features. Unity also comes with a fantastic editor, which VPE extends to make the table creation process as easy as possible. > [!Video https://www.youtube.com/embed/JxjdZ6mohfA] *An imported .vpx file in VPE, using Unitys' High Definition Render Pipeline.* -> [!Video https://www.youtube.com/embed/wHcKd_FExsE] +> [!Video https://www.youtube.com/embed/_CfZImFl1ME] Gottlieb's *Volley*, remodeled and retextured in Unity - -> [!NOTE] -> Technically, VPE is what we call a "library". A library is not executable per se, because it needs a host application. -> -> We will provide such a host application in the future, but for now you will need to create a new Unity project and add VPE as a package in order to run it. - ## Audience -This documentation is mainly aimed at table creators ("authors"). VPE is currently not in a state where it is usable by the general public ("players"). Documentation about how to setup VPE to play will follow at a later stage. +This documentation is mainly aimed at table creators ("authors"). VPE is currently not in a state where it is usable by the general public ("players"). Documentation about how to set up VPE to play will follow at a later stage. \ No newline at end of file From 0edf84ef52c8f62cbfc6eb60406da6d8c5709334 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 29 Oct 2023 00:40:54 +0200 Subject: [PATCH 153/159] doc: Vectorize text on main page logo. --- VisualPinball.Unity/Documentation~/index.md | 624 +++++++++++++----- .../template/vpe/public/main.css | 11 +- VisualPinball.Unity/Documentation~/vpe.svg | 26 - 3 files changed, 481 insertions(+), 180 deletions(-) delete mode 100644 VisualPinball.Unity/Documentation~/vpe.svg diff --git a/VisualPinball.Unity/Documentation~/index.md b/VisualPinball.Unity/Documentation~/index.md index 2ecc932be..51c3aad98 100644 --- a/VisualPinball.Unity/Documentation~/index.md +++ b/VisualPinball.Unity/Documentation~/index.md @@ -9,154 +9,484 @@ is_full: true Welcome to the documentation of the - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [Start here with the creator's guide](xref:vpe-overview). diff --git a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css index bf6ae6f52..bdf06c3fd 100644 --- a/VisualPinball.Unity/Documentation~/template/vpe/public/main.css +++ b/VisualPinball.Unity/Documentation~/template/vpe/public/main.css @@ -78,20 +78,17 @@ a { } /* landing svg art colors */ -svg .cls-1 { /* visual pinball engine */ +svg #text { /* visual pinball engine */ fill: var(--bs-body-color); - font-family: Asgalt-Regular, Asgalt; - font-size: 34.4px; - letter-spacing: .19em; } -svg .cls-2, .cls-3, .cls-4 { /* outer */ +svg #bg1 { /* outer */ stroke-width: 0; fill: var(--bs-body-bg) } -svg .cls-3 { /* logo */ +svg #logo { /* logo */ fill: var(--bs-body-color); } -svg .cls-4 { /* inner */ +svg #bg2 { /* inner */ fill: var(--vpe-body-bg-secondary); } diff --git a/VisualPinball.Unity/Documentation~/vpe.svg b/VisualPinball.Unity/Documentation~/vpe.svg deleted file mode 100644 index ca26aec8d..000000000 --- a/VisualPinball.Unity/Documentation~/vpe.svg +++ /dev/null @@ -1,26 +0,0 @@ - -AAAsZ2p1bWIAAAAeanVtZGMycGEAEQAQgAAAqgA4m3EDYzJwYQAAACxBanVtYgAAAEdqdW1kYzJtYQARABCAAACqADibcQN1cm46dXVpZDowMzY3MTJkZC0zN2U3LTQwNjctOGY3My1kNjJiNjc0OTA1OGUAAAABp2p1bWIAAAApanVtZGMyYXMAEQAQgAAAqgA4m3EDYzJwYS5hc3NlcnRpb25zAAAAAMpqdW1iAAAAJmp1bWRjYm9yABEAEIAAAKoAOJtxA2MycGEuYWN0aW9ucwAAAACcY2JvcqFnYWN0aW9uc4GjZmFjdGlvbmtjMnBhLmVkaXRlZG1zb2Z0d2FyZUFnZW50bUFkb2JlIEZpcmVmbHlxZGlnaXRhbFNvdXJjZVR5cGV4Rmh0dHA6Ly9jdi5pcHRjLm9yZy9uZXdzY29kZXMvZGlnaXRhbHNvdXJjZXR5cGUvdHJhaW5lZEFsZ29yaXRobWljTWVkaWEAAACsanVtYgAAAChqdW1kY2JvcgARABCAAACqADibcQNjMnBhLmhhc2guZGF0YQAAAAB8Y2JvcqVqZXhjbHVzaW9uc4GiZXN0YXJ0GMtmbGVuZ3RoGTs0ZG5hbWVuanVtYmYgbWFuaWZlc3RjYWxnZnNoYTI1NmRoYXNoWCBRy4VtZOjegibAlXtGwTG9jChO94sfwlcViv2jO9C6fWNwYWRJAAAAAAAAAAAAAAACC2p1bWIAAAAkanVtZGMyY2wAEQAQgAAAqgA4m3EDYzJwYS5jbGFpbQAAAAHfY2JvcqhoZGM6dGl0bGVvR2VuZXJhdGVkIEltYWdlaWRjOmZvcm1hdG1pbWFnZS9zdmcreG1samluc3RhbmNlSUR4LHhtcDppaWQ6OTAyOTU2MWUtYzBlYS00ZWMxLWE5MjQtZGM2MzZkYjlhN2Vmb2NsYWltX2dlbmVyYXRvcng2QWRvYmVfSWxsdXN0cmF0b3IvMjguMCBhZG9iZV9jMnBhLzAuNy42IGMycGEtcnMvMC4yNS4ydGNsYWltX2dlbmVyYXRvcl9pbmZvgb9kbmFtZXFBZG9iZSBJbGx1c3RyYXRvcmd2ZXJzaW9uZDI4LjD/aXNpZ25hdHVyZXgZc2VsZiNqdW1iZj1jMnBhLnNpZ25hdHVyZWphc3NlcnRpb25zgqJjdXJseCdzZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmFjdGlvbnNkaGFzaFgg66xm4WqDn3xgnOk59f7WI0GCp10rxJISEEb0ImTQK8GiY3VybHgpc2VsZiNqdW1iZj1jMnBhLmFzc2VydGlvbnMvYzJwYS5oYXNoLmRhdGFkaGFzaFggZTi6T30RavQw6UZvdKxtr4MkTknk06MnHdnGLSgwmD9jYWxnZnNoYTI1NgAAKEBqdW1iAAAAKGp1bWRjMmNzABEAEIAAAKoAOJtxA2MycGEuc2lnbmF0dXJlAAAAKBBjYm9y0oREoQE4JKNneDVjaGFpboJZBjMwggYvMIIEF6ADAgECAhAbWws72rDkXfLzDZ5U0drSMA0GCSqGSIb3DQEBCwUAMHUxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxIjAgBgNVBAMTGUFkb2JlIFByb2R1Y3QgU2VydmljZXMgRzMwHhcNMjMwMjAxMDAwMDAwWhcNMjQwMjAxMjM1OTU5WjCBoTERMA8GA1UEAwwIY2FpLXByb2QxHDAaBgNVBAsME0NvbnRlbnQgQ3JlZGVudGlhbHMxEzARBgNVBAoMCkFkb2JlIEluYy4xETAPBgNVBAcMCFNhbiBKb3NlMRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzEkMCIGCSqGSIb3DQEJARYVZ3JwLWNhaS1vcHNAYWRvYmUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA79MAp32GPZZBw7MpK0xuxWJZ2BwXMrmpbg+bvVC487/hbE1ji4PDYa8/UU8SPRHgW7t1pu3+L6j7EGH8ZBKdMCGug1ZhDmYWwHkX24cm1kPw+Fr73JOJhGUfkGZk6SJ+x1+tYG7TBR5SVMZGAXLSKALfUwQBW8/XeSINlhtG7B9/W+v/FEl5yCJOBQenbQUU9cXhMEg7cDndWAaV1zQSZkVh1zSWWfOaH9rQU3rIP5DL06ziScWA2fe1ONesHL21aJpXnrPjV1GN/2QeMR/jbGYpbO5tWy9r9oUpx4i6KmXlCpJWx1Jk+GaY62QnbbiLFpuY9jz1yq+xylLgm2UlwQIDAQAFo4IBjDCCAYgwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwHgYDVR0lBBcwFQYJKoZIhvcvAQEMBggrBgEFBQcDBDCBjgYDVR0gBIGGMIGDMIGABgkqhkiG9y8BAgMwczBxBggrBgEFBQcCAjBlDGNZb3UgYXJlIG5vdCBwZXJtaXR0ZWQgdG8gdXNlIHRoaXMgTGljZW5zZSBDZXJ0aWZpY2F0ZSBleGNlcHQgYXMgcGVybWl0dGVkIGJ5IHRoZSBsaWNlbnNlIGFncmVlbWVudC4wXQYDVR0fBFYwVDBSoFCgToZMaHR0cDovL3BraS1jcmwuc3ltYXV0aC5jb20vY2FfN2E1YzNhMGM3MzExNzQwNmFkZDE5MzEyYmMxYmMyM2YvTGF0ZXN0Q1JMLmNybDA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9wa2ktb2NzcC5zeW1hdXRoLmNvbTAfBgNVHSMEGDAWgBRXKXoyTcz+5DVOwB8kc85zU6vfajANBgkqhkiG9w0BAQsFAAOCAgEAV45Rmt8gCvxoo5+p/yTVPRWZu9jD+r3OXM61nvctE/hGsLkb4aQ+RHYtU515K6XvLDJIEo0xnW2PshoavM5QlkHlzdf2lqNy/V69bjcWP6FaS59Llln53ye8kfYCpf8qDH4Y8nU+LdX1x4vzIX4a1klUR6l9lN9VBRs/3tvfD9pL/r6oc6SFKNW4/o4m7aDyzDEHAjk7SoiTk4eKN1UmacEAxEQs6PdTZBfi52Y8GJenxOVEiJIP6AqKJl8Uj6aMMmw63ESfYpW7SXBEePPyxoMM7/3OzmHa6J+D5xF5tRZDmlY/kEX+zsIjU4s6J4SMy0eVX6dEBzlr/2z87woz0Hfl69EONN9lpUsUMKLLTUwD7aFQFODgsFR9xHId/HpidNP+n5Awna+zDfP+J9i0jazFL2gRGXZi6gwgZztNnWxa5qYN6U3NBakUOBi//PKY0TUjMubVPUqEJ0ghmKiLI3y/AM4DxBol10YAAWHNbl3nH+P3msm9ytjD7O4Z1k21CqRxySMMaXTd70xnWTVqc/TsX7qN3hC0JZE7wAh4KpGl4vxQGpx3uTwoZ+n69f+HDRfIKA9G7jwKYEt888Ko0Ycax/CEsD3yZ/Cas7qzGiwzJ53NfLR81IjLV+943+qF4e76AsV/0+A95xT5cVN6JtnKXC0NVneNNusdfK5UhkdZBqUwggahMIIEiaADAgECAhAMqLZUe4nm0gaJdc2Lm4niMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAlVTMSMwIQYDVQQKExpBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZDEdMBsGA1UECxMUQWRvYmUgVHJ1c3QgU2VydmljZXMxGTAXBgNVBAMTEEFkb2JlIFJvb3QgQ0EgRzIwHhcNMTYxMTI5MDAwMDAwWhcNNDExMTI4MjM1OTU5WjB1MQswCQYDVQQGEwJVUzEjMCEGA1UEChMaQWRvYmUgU3lzdGVtcyBJbmNvcnBvcmF0ZWQxHTAbBgNVBAsTFEFkb2JlIFRydXN0IFNlcnZpY2VzMSIwIAYDVQQDExlBZG9iZSBQcm9kdWN0IFNlcnZpY2VzIEczMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtx8uvb0Js1xIbP4Mg65sAepReCWkgD6Jp7GyiGTa9ol2gfn5HfOV/HiYjZiOz+TuHFU+DXNad86xEqgVeGVMlvIHGe/EHcKBxvEDXdlTXB5zIEkfl0/SGn7J6vTX8MNybfSi95eQDUOZ9fjCaq+PBFjS5ZfeNmzi/yR+MsA0jKKoWarSRCFFFBpUFQWfAgLyXOyxOnXQOQudjxNj6Wu0X0IB13+IH11WcKcWEWXM4j4jh6hLy29Cd3EoVG3oxcVenMF/EMgD2tXjx4NUbTNB1/g9+MR6Nw5Mhp5k/g3atNExAxhtugC+T3SDShSEJfs2quiiRUHtX3RhOcK1s1OJgT5s2s9xGy5/uxVpcAIaK2KiDJXW3xxN8nXPmk1NSVu/mxtfapr4TvSJbhrU7UA3qhQY9n4On2sbH1X1Tw+7LTek8KCA5ZDghOERPiIp/Jt893qov1bE5rJkagcVg0Wqjh89NhCaBA8VyRt3ovlGyCKdNV2UL3bn5vdFsTk7qqmp9makz1/SuVXYxIf6L6+8RXOatXWaPkmucuLE1TPOeP7S1N5JToFCs80l2D2EtxoQXGCR48K/cTUR5zV/fQ+hdIOzoo0nFn77Y8Ydd2k7/x9BE78pmoeMnw6VXYfXCuWEgj6p7jpbLoxQMoWMCVzlg72WVNhJFlSw4aD8fc6ezeECAwEAAaOCATQwggEwMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5hZG9iZS5jb20vYWRvYmVyb290ZzIuY3JsMA4GA1UdDwEB/wQEAwIBBjAUBgNVHSUEDTALBgkqhkiG9y8BAQcwVwYDVR0gBFAwTjBMBgkqhkiG9y8BAgMwPzA9BggrBgEFBQcCARYxaHR0cHM6Ly93d3cuYWRvYmUuY29tL21pc2MvcGtpL3Byb2Rfc3ZjZV9jcHMuaHRtbDAkBgNVHREEHTAbpBkwFzEVMBMGA1UEAxMMU1lNQy00MDk2LTMzMB0GA1UdDgQWBBRXKXoyTcz+5DVOwB8kc85zU6vfajAfBgNVHSMEGDAWgBSmHOFtVCRMqI9Icr9uqYzV5Owx1DANBgkqhkiG9w0BAQsFAAOCAgEAcc7lB4ym3C3cyOA7ZV4AkoGV65UgJK+faThdyXzxuNqlTQBlOyXBGFyevlm33BsGO1mDJfozuyLyT2+7IVxWFvW5yYMV+5S1NeChMXIZnCzWNXnuiIQSdmPD82TEVCkneQpFET4NDwSxo8/ykfw6Hx8fhuKz0wjhjkWMXmK3dNZXIuYVcbynHLyJOzA+vWU3sH2T0jPtFp7FN39GZne4YG0aVMlnHhtHhxaXVCiv2RVoR4w1QtvKHQpzfPObR53Cl74iLStGVFKPwCLYRSpYRF7J6vVS/XxW4LzvN2b6VEKOcvJmN3LhpxFRl3YYzW+dwnwtbuHW6WJlmjffbLm1MxLFGlG95aCz31X8wzqYNsvb9+5AXcv8Ll69tLXmO1OtsY/3wILNUEp4VLZTE3wqm3n8hMnClZiiKyZCS7L4E0mClbx+BRSMH3eVo6jgve41/fK3FQM4QCNIkpGs7FjjLy+ptC+JyyWqcfvORrFV/GOgB5hD+G5ghJcIpeigD/lHsCRYsOa5sFdqREhwIWLmSWtNwfLZdJ3dkCc7yRpm3gal6qRfTkYpxTNxxKyvKbkaJDoxR9vtWrC3iNrQd9VvxC3TXtuzoHbqumeqgcAqefWF9u6snQ4Q9FkXzeuJArNuSvPIhgBjVtggH0w0vm/lmCQYiC/Y12GeCxfgYlL33btmc2lnVHN0oWl0c3RUb2tlbnOBoWN2YWxZF0Ewghc9MAMCAQAwghc0BgkqhkiG9w0BBwKgghclMIIXIQIBAzEPMA0GCWCGSAFlAwQCAQUAMIGDBgsqhkiG9w0BCRABBKB0BHIwcAIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIIOmDi9fuuYnRafLHrNjXnTO4/RQb5wEjAWJ0FYc/zqsAhEA34n7Dzh2JYgb2cBdNLCI5BgPMjAyMzEwMTkyMTUxNTdaAgkA4SALCeL5iRCgghMJMIIGwjCCBKqgAwIBAgIQBUSv85SdCDmmv9s/X+VhFjANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTIzMDcxNDAwMDAwMFoXDTM0MTAxMzIzNTk1OVowSDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKNTRYcdg45brD5UsyPgz5/X5dLnXaEOCdwvSKOXejsqnGfcYhVYwamTEafNqrJq3RApih5iY2nTWJw1cb86l+uUUI8cIOrHmjsvlmbjaedp/lvD1isgHMGXlLSlUIHyz8sHpjBoyoNC2vx/CSSUpIIa2mq62DvKXd4ZGIX7ReoNYWyd/nFexAaaPPDFLnkPG2ZS48jWPl/aQ9OE9dDH9kgtXkV1lnX+3RChG4PBuOZSlbVH13gpOWvgeFmX40QrStWVzu8IF+qCZE3/I+PKhu60pCFkcOvV5aDaY7Mu6QXuqvYk9R28mxyyt1/f8O52fTGZZUdVnUokL6wrl76f5P17cz4y7lI0+9S769SgLDSb495uZBkHNwGRDxy1Uc2qTGaDiGhiu7xBG3gZbeTZD+BYQfvYsSzhUa+0rRUGFOpiCBPTaR58ZE2dD9/O0V6MqqtQFcmzyrzXxDtoRKOlO0L9c33u3Qr/eTQQfqZcClhMAD6FaXXHg2TWdc2PEnZWpST618RrIbroHzSYLzrqawGw9/sqhux7UjipmAmhcbJsca8+uG+W1eEQE/5hRwqM/vC2x9XH3mwk8L9CgsqgcT2ckpMEtGlwJw1Pt7U20clfCKRwo+wK8REuZODLIivK8SgTIUlRfgZm0zu++uuRONhRB8qUt+JQofM604qDy0B7AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFKW27xPn783QZKHVVqllMaPe1eNJMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBAIEa1t6gqbWYF7xwjU+KPGic2CX/yyzkzepdIpLsjCICqbjPgKjZ5+PF7SaCinEvGN1Ott5s1+FgnCvt7T1IjrhrunxdvcJhN2hJd6PrkKoS1yeF844ektrCQDifXcigLiV4JZ0qBXqEKZi2V3mP2yZWK7Dzp703DNiYdk9WuVLCtp04qYHnbUFcjGnRuSvExnvPnPp44pMadqJpddNQ5EQSviANnqlE0PjlSXcIWiHFtM+YlRpUurm8wWkZus8W8oM3NG6wQSbd3lqXTzON1I13fXVFoaVYJmoDRd7ZULVQjK9WvUzF4UbFKNOt50MAcN7MmJ4ZiQPq1JE3701S88lgIcRWR+3aEUuMMsOI5ljitts++V+wQtaP4xeR0arAVeOGv6wnLEHQmjNKqDbUuXKWfpd5OEhfysLcPTLfddY2Z1qJ+Panx+VPNTwAvb6cKmx5AdzaROY63jg7B145WPR8czFVoIARyxQMfq68/qTreWWqaNYiyjvrmoI1VygWy2nyMpqy0tg6uLFGhmu6F/3Ed2wVbK6rr3M66ElGt9V/zLY4wNjsHPW2obhDLN9OTH0eaHDAdwrUAuBcYLso/zjlUlrWrBciI0707NMX+1Br/wd3H3GXREHJuEbTbDJ8WC9nR2XlG3O2mflrLAZG70Ee8PBf4NvZrZCARK+AEEGKMIIGrjCCBJagAwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUDxPKRN6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1ATCyZzlm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW1OcoLevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS8nZH92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jBZHRAp8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCYJn+gGkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucfWmyU8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLcGEh/FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNFYLwjjVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI+RQQEgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjASvUaetdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJLKftwig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgWvalWzxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2MvGQmh2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSumScbqyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJxLafzYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un8WbDQc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SVe+0KXzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4k9Tm8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJDwq9gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr5n8apIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBY0wggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZIhvcNAQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVowYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zCpyUuySE98orYWcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J58soR0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6Zu53yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQecN4x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4bA3VdeGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCUtNJhbesz2cXfSwQAzH0clcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvoZKYz0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCPorF+CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8jLfR+cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDGCA3YwggNyAgEBMHcwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQBUSv85SdCDmmv9s/X+VhFjANBglghkgBZQMEAgEFAKCB0TAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIzMTAxOTIxNTE1N1owKwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQUZvArMsLCyQ+CXc6qisnGTxmcz0AwLwYJKoZIhvcNAQkEMSIEIOA/0nBy5DVVGkO7Ul9gt8qjHnvPyu9xLb0wMN7Yzs0uMDcGCyqGSIb3DQEJEAIvMSgwJjAkMCIEINL25G3tdCLM0dRAV2hBNm+CitpVmq4zFq9NGprUDHgoMA0GCSqGSIb3DQEBAQUABIICAEzB5v31oQObu2ETlzsQY8mVOphH18M7c9aD+DOXz1tUc/k1ttaBnKOm42BKsdTCkTmluGDNnd+Mk672MP6VC4oKrjlR1cI5imNFf5srmp8Q8RcHZxT2VEO7rfTido1Dg4zx8uq4lMv/p69Bc+DZb2nGTUC7Gf6cvMtQnQWgpMZOsvGVaUtuJL7V3jk2a2CebjhweTZUx+pWLBPb5hg776X4scUXDN9BOF8BeAGXtagFo10zbo4ttr4IoCn9JNAdVHT0706cVL/LF1ckDRQVYrLsvCjVw9kE3fDWWeD/st/2wBiL3nvUjnGxZho1gsozOenQLTArjEZSTDCFzAXLZwbfQNnAK67MqdeJd6iBmaFNgXpADbK0lUs39oxRqabVYsht+H1Onm7WxqmENoZAEF53y7jFMCYq9G8DGa7jqnCQfRBCTj1VN/qV73ZtkwkuhY0EAd8waPg+IOkY0+Rt2MkWMfiQbVLn5RQcnfSs6lJGs1WAofvVeeWqd4BZ/XxbfuTs3kItzFQyfSMJGVt7thAvdFuIp9CGdZjXLRRABxomSj7YfOjNRak3kvK/LApdnaosPJILFZYPwj3/B7Jjgl0GYrNIcK1IFz+JLvM3g/7ppPY5hHPSMHojHtkzzJeE6jPB3Tq0XnoPyrG+mk5DmwxlQjtcNMaBFTe2lCTXounYY3BhZFkCsgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPZZAQAMB3yr2NRna25aL/kkNcUWBa54HxmPICMif5UIddMz3rRqt4abkvVlrVotfUbm/9rbEsmprBQa7X+G47IkXbh35I+wG7H233UIunLEDbPBipbZL4C5P2CSKvWYYgFy0NhAtt7coS34N6+lU+ZmaPD9p+rQyHvf7I4WE3s5ERmw3SqmE2peBiPP1FbSXWXzF5roS8eJXuReVpDd+86qzsyiH5vFq4fmvXhzVcS7hmHxWEpBu1sHpVxZx82nAhhsQIyrx/Ck72FVWP6/Cnnem0Ex6RZ4HFPHCuh5iMMqJc0XL28UsfxQj6FA4qGGYKfvSkJ4cTErZFnkj/wmgNlU/QXk - - - - - - - - - VISUAL PINBALL ENGINE - \ No newline at end of file From b043a0cca9a0bc9c81f02036049075ec6282eee4 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 29 Oct 2023 01:04:36 +0200 Subject: [PATCH 154/159] dots: Finally DOTS-free! Kicker mesh data and flipper correction state now use unmanaged data through pointers. --- .../Import/VpxSceneConverter.cs | 1 - .../VPT/PrimitiveTests.cs | 1 - .../Collections/NativeCurve.cs | 124 ++++++++++++++ .../Collections/NativeCurve.cs.meta | 3 + .../Collections/UnmanagedArray.cs | 57 +++++++ .../Collections/UnmanagedArray.cs.meta | 3 + .../Game/PhysicsColliderExtensions.cs | 144 ----------------- .../Game/PhysicsColliderExtensions.cs.meta | 3 - .../VisualPinball.Unity/Game/PhysicsEngine.cs | 1 - .../Game/PhysicsPopulateJob.cs | 1 - .../VisualPinball.Unity/Game/PhysicsState.cs | 33 +++- .../Game/PhysicsStaticCollision.cs | 6 +- .../Game/PhysicsUpdateJob.cs | 1 - .../Physics/Collider/CircleCollider.cs | 13 -- .../Physics/Collider/Collider.cs | 2 - .../Physics/Collider/ICollider.cs | 3 - .../Physics/Collider/Line3DCollider.cs | 12 -- .../Physics/Collider/LineCollider.cs | 13 -- .../Physics/Collider/LineSlingshotCollider.cs | 12 -- .../Physics/Collider/LineZCollider.cs | 13 -- .../Physics/Collider/PlaneCollider.cs | 13 -- .../Physics/Collider/PointCollider.cs | 13 -- .../Physics/Collider/TriangleCollider.cs | 13 -- .../Collision/ColliderAllocationJob.cs | 151 ------------------ .../Collision/ColliderAllocationJob.cs.meta | 11 -- .../Physics/Collision/ColliderBlob.cs | 25 --- .../Physics/Collision/ColliderBlob.cs.meta | 11 -- .../Physics/Collision/ColliderData.cs | 25 --- .../Physics/Collision/ColliderData.cs.meta | 11 -- .../Physics/Collision/ContactBufferElement.cs | 5 +- .../VPT/AnimationComponent.cs | 12 -- .../VPT/Flipper/FlipperCollider.cs | 16 -- .../VPT/Flipper/FlipperCorrection.cs | 15 +- .../VPT/Flipper/FlipperCorrectionBlob.cs | 29 ---- .../VPT/Flipper/FlipperCorrectionBlob.cs.meta | 11 -- .../VPT/Flipper/FlipperCorrectionState.cs | 55 ++++++- .../VPT/Gate/GateCollider.cs | 13 -- .../VPT/IMainRenderableComponent.cs | 2 - .../VPT/Kicker/KickerCollider.cs | 8 +- .../VPT/Kicker/KickerColliderMeshData.cs | 51 ++++-- .../VPT/Kicker/KickerComponent.cs | 5 +- .../VPT/Kicker/KickerState.cs | 9 +- .../VPT/MainRenderableComponent.cs | 8 - .../VPT/Mech/RotatorComponent.cs | 2 - .../VPT/Plunger/PlungerCollider.cs | 13 -- .../VPT/Spinner/SpinnerCollider.cs | 13 -- .../VPT/Surface/SlingshotComponent.cs | 2 - .../VPT/Trigger/TriggerComponent.cs | 32 +--- .../VPT/Trigger/TriggerState.cs | 9 +- package.json | 1 - 50 files changed, 345 insertions(+), 685 deletions(-) create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections/NativeCurve.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections/NativeCurve.cs.meta create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs create mode 100644 VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderData.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderData.cs.meta delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs delete mode 100644 VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs.meta diff --git a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs index b72bd03ed..fe26430bf 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Editor/Import/VpxSceneConverter.cs @@ -20,7 +20,6 @@ using System.Linq; using System.Reflection; using NLog; -using Unity.Scenes; using UnityEditor; using UnityEditor.Formats.Fbx.Exporter; using UnityEditor.SceneManagement; diff --git a/VisualPinball.Unity/VisualPinball.Unity.Test/VPT/PrimitiveTests.cs b/VisualPinball.Unity/VisualPinball.Unity.Test/VPT/PrimitiveTests.cs index 9406aa9a6..f80dabd3a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity.Test/VPT/PrimitiveTests.cs +++ b/VisualPinball.Unity/VisualPinball.Unity.Test/VPT/PrimitiveTests.cs @@ -21,7 +21,6 @@ using VisualPinball.Engine.Test.VPT.Primitive; using VisualPinball.Engine.VPT.Table; using VisualPinball.Unity.Editor; -using Assert = Unity.Assertions.Assert; namespace VisualPinball.Unity.Test { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/NativeCurve.cs b/VisualPinball.Unity/VisualPinball.Unity/Collections/NativeCurve.cs new file mode 100644 index 000000000..2779d7d1d --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/NativeCurve.cs @@ -0,0 +1,124 @@ +using System; +using System.Runtime.CompilerServices; +using Unity.Collections; +using UnityEngine; +using static Unity.Mathematics.math; + +namespace VisualPinball.Unity.Collections +{ + /// + /// Burst friendly curve implementation used to efficiently work with animation curves in the job system. + /// + public struct NativeCurve : IDisposable + { + /// + /// Informs if the native data structure has an allocated memory buffer. + /// + public bool isCreated => m_Values.IsCreated; + + NativeArray m_Values; + WrapMode m_PreWrapMode; + WrapMode m_PostWrapMode; + + void InitializeValues(int count, Allocator allocator = Allocator.Persistent) + { + if (m_Values.IsCreated) + m_Values.Dispose(); + + m_Values = new NativeArray(count, allocator, NativeArrayOptions.UninitializedMemory); + } + + /// + /// Re-initialize native curve data with new Animation curve. + /// + /// Curve ground truth to initialize from. + /// Number of samples to use when converting from animation curve to native curve. + public void Update(AnimationCurve curve, int resolution) + { + if (curve == null) + return; + + m_PreWrapMode = curve.preWrapMode; + m_PostWrapMode = curve.postWrapMode; + + if (!m_Values.IsCreated || m_Values.Length != resolution) + InitializeValues(resolution); + + for (int i = 0; i < resolution; i++) + m_Values[i] = curve.Evaluate((float)i / (float)resolution); + } + + /// + /// Evaluate value along the underlying native curve. + /// + /// Location along curve to evaluate. + /// Value along curve at given location t. + public float Evaluate(float t) + { + var count = m_Values.Length; + + if (count == 1) + return m_Values[0]; + + if (t < 0f) + { + switch (m_PreWrapMode) + { + default: + return m_Values[0]; + case WrapMode.Loop: + t = 1f - (abs(t) % 1f); + break; + case WrapMode.PingPong: + t = PingPong(t, 1f); + break; + } + } + else if (t > 1f) + { + switch (m_PostWrapMode) + { + default: + return m_Values[count - 1]; + case WrapMode.Loop: + t %= 1f; + break; + case WrapMode.PingPong: + t = PingPong(t, 1f); + break; + } + } + + var it = t * (count - 1); + + var lower = (int)it; + var upper = lower + 1; + if (upper >= count) + upper = count - 1; + + return lerp(m_Values[lower], m_Values[upper], it - lower); + } + + /// + /// Dispose native collection. + /// + public void Dispose() + { + if (m_Values.IsCreated) + m_Values.Dispose(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + float Repeat(float t, float length) + { + return clamp(t - floor(t / length) * length, 0, length); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + float PingPong(float t, float length) + { + t = Repeat(t, length * 2f); + return length - abs(t - length); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/NativeCurve.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Collections/NativeCurve.cs.meta new file mode 100644 index 000000000..20876e515 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/NativeCurve.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3b29d38c75fe47968f0c82207d784ba6 +timeCreated: 1698489496 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs b/VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs new file mode 100644 index 000000000..8e5d28c30 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs @@ -0,0 +1,57 @@ +// MIT License +// +// Copyright (c) 2022 Timothy Raines +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +using System; +using Unity.Collections.LowLevel.Unsafe; + +namespace VisualPinball.Unity +{ + public readonly unsafe struct UnmanagedArray where T : unmanaged + { + private readonly void* _buffer; + public readonly int Length; + + public UnmanagedArray(void* buffer, int length) + { + _buffer = buffer; + Length = length; + } + + public T this[int index] + { + get { + if (index < 0 || index >= Length) { + throw new IndexOutOfRangeException(); + } + return UnsafeUtility.ReadArrayElement(_buffer, index); + } + } + + public ref T GetAsRef(int index) + { + if (index < 0 || index >= Length) { + throw new IndexOutOfRangeException(); + } + return ref UnsafeUtility.ArrayElementAsRef(_buffer, index); + } + } +} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs.meta new file mode 100644 index 000000000..d95738c95 --- /dev/null +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b19e3cbc43a1490a80a425f1ba15d1ec +timeCreated: 1698533074 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs deleted file mode 100644 index 166345ae6..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs +++ /dev/null @@ -1,144 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; - -namespace VisualPinball.Unity -{ - public static class PhysicsColliderExtensions - { - internal static int GetId(this BlobAssetReference colliders, int index) - => colliders.Value.Colliders[index].Value.Id; - - internal static ColliderType GetType(this BlobAssetReference colliders, int index) - => colliders.Value.Colliders[index].Value.Type; - - internal static float GetFriction(this BlobAssetReference colliders, int index) - => colliders.Value.Colliders[index].Value.Material.Friction; - - internal static Aabb GetAabb(this BlobAssetReference colliders, int index) - => colliders.Value.Colliders[index].Value.Bounds().Aabb; - - internal static unsafe ref CircleCollider Circle(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var circleCollider = (CircleCollider*) cPtr; - return ref UnsafeUtility.AsRef(circleCollider); - } - } - - internal static unsafe ref PlaneCollider Plane(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var planeCollider = (PlaneCollider*) cPtr; - return ref UnsafeUtility.AsRef(planeCollider); - } - } - - internal static unsafe ref SpinnerCollider Spinner(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var spinnerCollider = (SpinnerCollider*) cPtr; - return ref UnsafeUtility.AsRef(spinnerCollider); - } - } - - internal static unsafe ref GateCollider Gate(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var gateCollider = (GateCollider*) cPtr; - return ref UnsafeUtility.AsRef(gateCollider); - } - } - - internal static unsafe ref LineCollider Line(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var lineCollider = (LineCollider*) cPtr; - return ref UnsafeUtility.AsRef(lineCollider); - } - } - - internal static unsafe ref TriangleCollider Triangle(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var triangleCollider = (TriangleCollider*) cPtr; - return ref UnsafeUtility.AsRef(triangleCollider); - } - } - - internal static unsafe ref Line3DCollider Line3D(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var line3DCollider = (Line3DCollider*) cPtr; - return ref UnsafeUtility.AsRef(line3DCollider); - } - } - - internal static unsafe ref LineSlingshotCollider LineSlingShot(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var lineSlingshotCollider = (LineSlingshotCollider*) cPtr; - return ref UnsafeUtility.AsRef(lineSlingshotCollider); - } - } - - internal static unsafe ref PointCollider Point(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var pointCollider = (PointCollider*) cPtr; - return ref UnsafeUtility.AsRef(pointCollider); - } - } - - internal static unsafe ref LineZCollider LineZ(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var lineZCollider = (LineZCollider*) cPtr; - return ref UnsafeUtility.AsRef(lineZCollider); - } - } - - internal static unsafe ref FlipperCollider Flipper(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var flipperCollider = (FlipperCollider*) cPtr; - return ref UnsafeUtility.AsRef(flipperCollider); - } - } - - internal static unsafe ref PlungerCollider Plunger(this in BlobAssetReference colliders, int index) - { - ref var coll = ref colliders.Value.Colliders[index].Value; - fixed (Collider* cPtr = &coll) { - var plungerCollider = (PlungerCollider*) cPtr; - return ref UnsafeUtility.AsRef(plungerCollider); - } - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs.meta deleted file mode 100644 index 56a88bd5c..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsColliderExtensions.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: d5d02c30bc514422ad04ca0f05eda526 -timeCreated: 1681165885 \ No newline at end of file diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index 083e502f5..d37daa8a0 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -20,7 +20,6 @@ using System.Diagnostics; using NativeTrees; using Unity.Collections; -using Unity.Entities; using Unity.Jobs; using Unity.Mathematics; using UnityEngine; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs index 8713b4e53..eaa43a57e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsPopulateJob.cs @@ -1,7 +1,6 @@ using NativeTrees; using Unity.Burst; using Unity.Collections; -using Unity.Entities; using Unity.Jobs; namespace VisualPinball.Unity diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index 996d8072f..e8e36e0e6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; using NativeTrees; using Unity.Collections; using VisualPinball.Engine.VPT; @@ -21,7 +22,7 @@ namespace VisualPinball.Unity { - internal struct PhysicsState + internal struct PhysicsState : IDisposable { internal PhysicsEnv Env; internal NativeOctree Octree; @@ -183,5 +184,35 @@ private bool IsInactiveDropTarget(int colliderId) } #endregion + + public void Dispose() + { + Env.Dispose(); + Octree.Dispose(); + Colliders.Dispose(); + InsideOfs.Dispose(); + Balls.Dispose(); + BumperStates.Dispose(); + DropTargetStates.Dispose(); + FlipperStates.Dispose(); + GateStates.Dispose(); + HitTargetStates.Dispose(); + using (var enumerator = KickerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + enumerator.Current.Value.Dispose(); + } + } + KickerStates.Dispose(); + PlungerStates.Dispose(); + SpinnerStates.Dispose(); + SurfaceStates.Dispose(); + using (var enumerator = TriggerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + enumerator.Current.Value.Dispose(); + } + } + TriggerStates.Dispose(); + DisabledCollisionItems.Dispose(); + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index a04554bc7..e4aa7f32d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -168,9 +168,9 @@ private static void TriggerCollide(ref BallState ball, ref PhysicsState state, i if (triggerState.FlipperCorrection.IsEnabled) { if (triggerState.Animation.UnHitEvent) { - ref var flipperCorrectionBlob = ref triggerState.FlipperCorrection.Value.Value; - ref var fs = ref state.FlipperStates.GetValueByRef(flipperCorrectionBlob.FlipperItemId); - FlipperCorrection.OnBallLeaveFlipper(ref ball, ref flipperCorrectionBlob, in fs.Movement, in fs.Tricks, in fs.Static, state.Env.TimeMsec); + ref var flipperCorrectionState = ref triggerState.FlipperCorrection; + ref var fs = ref state.FlipperStates.GetValueByRef(flipperCorrectionState.FlipperItemId); + FlipperCorrection.OnBallLeaveFlipper(ref ball, ref flipperCorrectionState, in fs.Movement, in fs.Tricks, in fs.Static, state.Env.TimeMsec); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs index 45230352d..f247a812c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsUpdateJob.cs @@ -16,7 +16,6 @@ using NativeTrees; using Unity.Burst; using Unity.Collections; -using Unity.Entities; using Unity.Jobs; using VisualPinball.Engine.Common; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs index bdcda2115..bd18a8a48 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs @@ -14,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; using VisualPinball.Engine.VPT; @@ -56,17 +54,6 @@ public CircleCollider(float2 center, float radius, float zLow, float zHigh, Coll _zLow = zLow; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(CircleCollider) - ); - } - #region Narrowphase public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallState ball, float dTime) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs index 587ba3a23..7cc531caa 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Collider.cs @@ -16,11 +16,9 @@ using System; using Unity.Collections; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Game; using VisualPinball.Engine.VPT; -using Random = Unity.Mathematics.Random; namespace VisualPinball.Unity { diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ICollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ICollider.cs index 319efa6d6..2c480eb8e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ICollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ICollider.cs @@ -14,14 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { public interface ICollider { int Id { get; } - void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders); ColliderBounds Bounds { get; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs index 467d396d5..ebbf1ec4a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/Line3DCollider.cs @@ -16,7 +16,6 @@ using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; namespace VisualPinball.Unity @@ -92,17 +91,6 @@ public Line3DCollider(float3 v1, float3 v2, ColliderInfo info) : this() )); } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(Line3DCollider) - ); - } - #region Narrowphase public float HitTest(ref CollisionEventData collEvent, in BallState ball, float dTime) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs index 8ac6be29d..9ace858cb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineCollider.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; using VisualPinball.Engine.VPT; @@ -68,17 +66,6 @@ public LineCollider(float2 v1, float2 v2, float zLow, float zHigh, ColliderInfo CalcNormal(); } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(LineCollider) - ); - } - public void CalcNormal() { var vT = new float2(V1.x - V2.x, V1.y - V2.y); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs index 3ff50db19..57886a1a5 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineSlingshotCollider.cs @@ -16,7 +16,6 @@ using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Game; @@ -62,17 +61,6 @@ public LineSlingshotCollider(float force, float2 v1, float2 v2, float zLow, floa CalcNormal(); } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(LineSlingshotCollider) - ); - } - private void CalcNormal() { var vT = new float2(V1.x - V2.x, V1.y - V2.y); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs index 604923a06..c8c38e877 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/LineZCollider.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; @@ -47,17 +45,6 @@ public int Id _zHigh )); - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(LineZCollider) - ); - } - public LineZCollider(float2 xy, float zLow, float zHigh, ColliderInfo info) : this() { Header.Init(info, ColliderType.LineZ); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index 872195fb6..691a31615 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -14,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Common; @@ -45,17 +43,6 @@ public PlaneCollider(float3 normal, float distance, ColliderInfo info) : this() _distance = distance; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(PlaneCollider) - ); - } - public override string ToString() => $"PlaneCollider[{Header.ItemId}] {_distance} at ({_normal.x}/{_normal.y}/{_normal.z})"; #region Narrowphase diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs index 5b09ccf2a..94f6b3956 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PointCollider.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; @@ -49,17 +47,6 @@ public PointCollider(float3 p, ColliderInfo info) : this() P = p; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(PointCollider) - ); - } - #region Narrowphase public float HitTest(ref CollisionEventData collEvent, in BallState ball, float dTime) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs index 5bb509378..0959028ea 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/TriangleCollider.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; using VisualPinball.Engine.VPT; @@ -63,17 +61,6 @@ public TriangleCollider(float3 rgv0, float3 rgv1, float3 rgv2, ColliderInfo info _normal = math.normalizesafe(math.cross(e0, e1)); } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(TriangleCollider) - ); - } - public static bool IsDegenerate(float3 rg0, float3 rg1, float3 rg2) { var e0 = rg2 - rg0; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs deleted file mode 100644 index e9791d60d..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs +++ /dev/null @@ -1,151 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using System; -using Unity.Burst; -using Unity.Collections; -using Unity.Entities; -using Unity.Jobs; -using Unity.Profiling; - -namespace VisualPinball.Unity -{ - /// - /// This job converts a list of managed ICollider objects into unmanaged Collider structs.
- /// - /// However, the output is not a list, but a NativeArray of length of 1, containing a BlobAssetReference - /// of ColliderBlob, which contains a BlobArray of BlobPtr of Collider. - ///
- /// - /// - /// for (var i = 0; i < BlobAsset[0].Value.Colliders.Length; i++) { - /// var collider = BlobAsset[0].Value.Colliders[i].Value; - /// } - /// - /// - [BurstCompile] - internal struct ColliderAllocationJob : IJob, IDisposable - { - [ReadOnly] private NativeList _circleColliders; - [ReadOnly] private NativeList _flipperColliders; - [ReadOnly] private NativeList _gateColliders; - [ReadOnly] private NativeList _line3DColliders; - [ReadOnly] private NativeList _lineSlingshotColliders; - [ReadOnly] private NativeList _lineColliders; - [ReadOnly] private NativeList _lineZColliders; - [ReadOnly] private NativeList _plungerColliders; - [ReadOnly] private NativeList _pointColliders; - [ReadOnly] private NativeList _spinnerColliders; - [ReadOnly] private NativeList _triangleColliders; - [ReadOnly] private NativeList _planeColliders; - - /// - /// The result: A blob asset of allocated Collider structs that can be casted to - /// their respective type. - /// - public NativeArray> BlobAsset; - - public ColliderAllocationJob(ref ColliderReference colliderList) : this() - { - var perfMarker = new ProfilerMarker("ColliderAllocationJob.ctr"); - perfMarker.Begin(); - - _circleColliders = colliderList.CircleColliders; - _flipperColliders = colliderList.FlipperColliders; - _gateColliders = colliderList.GateColliders; - _line3DColliders = colliderList.Line3DColliders; - _lineSlingshotColliders = colliderList.LineSlingshotColliders; - _lineColliders = colliderList.LineColliders; - _lineZColliders = colliderList.LineZColliders; - _plungerColliders = colliderList.PlungerColliders; - _pointColliders = colliderList.PointColliders; - _spinnerColliders = colliderList.SpinnerColliders; - _triangleColliders = colliderList.TriangleColliders; - _planeColliders = colliderList.PlaneColliders; - - BlobAsset = new NativeArray>(1, Allocator.Persistent); - - perfMarker.End(); - } - public void Execute() - { - var builder = new BlobBuilder(Allocator.Temp); - ref var root = ref builder.ConstructRoot(); - var count = _circleColliders.Length + _flipperColliders.Length + _gateColliders.Length + _line3DColliders.Length - + _lineSlingshotColliders.Length + _lineColliders.Length + _lineZColliders.Length + _plungerColliders.Length - + _pointColliders.Length + _spinnerColliders.Length + _triangleColliders.Length + _planeColliders.Length; - - var colliders = builder.Allocate(ref root.Colliders, count); - - // copy generated colliders into blob array - for (var i = 0; i < _circleColliders.Length; i++) { - _circleColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _flipperColliders.Length; i++) { - _flipperColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _gateColliders.Length; i++) { - _gateColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _line3DColliders.Length; i++) { - _line3DColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _lineSlingshotColliders.Length; i++) { - _lineSlingshotColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _lineColliders.Length; i++) { - _lineColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _lineZColliders.Length; i++) { - _lineZColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _planeColliders.Length; i++) { - _planeColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _plungerColliders.Length; i++) { - _plungerColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _pointColliders.Length; i++) { - _pointColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _spinnerColliders.Length; i++) { - _spinnerColliders[i].Allocate(builder, ref colliders); - } - for (var i = 0; i < _triangleColliders.Length; i++) { - _triangleColliders[i].Allocate(builder, ref colliders); - } - - BlobAsset[0] = builder.CreateBlobAssetReference(Allocator.Persistent); - builder.Dispose(); - } - - public void Dispose() - { - _circleColliders.Dispose(); - _flipperColliders.Dispose(); - _gateColliders.Dispose(); - _line3DColliders.Dispose(); - _lineSlingshotColliders.Dispose(); - _lineColliders.Dispose(); - _lineZColliders.Dispose(); - _planeColliders.Dispose(); - _plungerColliders.Dispose(); - _pointColliders.Dispose(); - _spinnerColliders.Dispose(); - _triangleColliders.Dispose(); - } - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs.meta deleted file mode 100644 index b3cf36e79..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderAllocationJob.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e1b39a65578966b45abdf218d03e27c8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs deleted file mode 100644 index fa96808cb..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinball.Unity -{ - internal struct ColliderBlob : IComponentData - { - public BlobArray> Colliders; - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs.meta deleted file mode 100644 index 17630be91..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderBlob.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dce2e781114bd3a48b96e49445bf7a72 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderData.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderData.cs deleted file mode 100644 index 13b580640..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderData.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; - -namespace VisualPinball.Unity -{ - internal struct ColliderData : IComponentData - { - public BlobAssetReference Value; - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderData.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderData.cs.meta deleted file mode 100644 index 7a281dde0..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ColliderData.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c502479a16d8f54418483b12c2b5f9a0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactBufferElement.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactBufferElement.cs index 50e2d19ad..dafe9c893 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactBufferElement.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collision/ContactBufferElement.cs @@ -14,12 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; - namespace VisualPinball.Unity { - [InternalBufferCapacity(8)] - internal struct ContactBufferElement : IBufferElementData + internal struct ContactBufferElement { public CollisionEventData CollEvent; public int BallId; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs index 950e0cddb..a5700fba1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/AnimationComponent.cs @@ -14,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System; -using Unity.Entities; using VisualPinball.Engine.VPT; namespace VisualPinball.Unity @@ -31,15 +29,5 @@ private void Awake() { RegisterPhysics(); } - - private Entity MainEntity { - get { - var ma = MainComponent; - if (ma == null) { - throw new InvalidOperationException("Cannot find main component of " + name + "."); - } - return ma.Entity; - } - } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs index e9dfa6d00..2ad84f096 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCollider.cs @@ -16,8 +16,6 @@ using NLog; using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; using VisualPinball.Engine.Game; @@ -142,20 +140,6 @@ private static float ClampDegrees(float angle) return deg > 180 ? deg - 360 : deg; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - var bounds = Bounds; - bounds.ColliderId = Header.Id; - Bounds = bounds; - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(FlipperCollider) - ); - } - #endregion #region Narrowphase diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs index 74db32a91..9f9d475b1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrection.cs @@ -14,25 +14,22 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using Unity.Mathematics; namespace VisualPinball.Unity { internal static class FlipperCorrection { - public static void OnBallLeaveFlipper(ref BallState ballState, ref FlipperCorrectionBlob flipperCorrectionBlob, + public static void OnBallLeaveFlipper(ref BallState ballState, ref FlipperCorrectionState flipperCorrectionState, in FlipperMovementState flipperMovementState, in FlipperTricksData tricks, in FlipperStaticData flipperStaticData, uint timeMs) { var timeSinceFlipperStartedRotatingToEndMs = timeMs - flipperMovementState.StartRotateToEndTime; // Time delay overrun test - if (timeSinceFlipperStartedRotatingToEndMs > flipperCorrectionBlob.TimeDelayMs) + if (timeSinceFlipperStartedRotatingToEndMs > flipperCorrectionState.TimeDelayMs) return; - ref var velocities = ref flipperCorrectionBlob.Velocities; - ref var polarities = ref flipperCorrectionBlob.Polarities; var angleCur = flipperMovementState.Angle; var ballPosition = ballState.Position; @@ -65,7 +62,7 @@ public static void OnBallLeaveFlipper(ref BallState ballState, ref FlipperCorrec partialFlipCoef = math.abs(partialFlipCoef - 1F); // Velocity correction - var velCoef = LinearEnvelopeEven(ballPos, ref velocities); + var velCoef = LinearEnvelopeEven(ballPos, flipperCorrectionState.Velocities); var velCoefInit = velCoef; if (partialFlipCoef < 1) { @@ -76,7 +73,7 @@ public static void OnBallLeaveFlipper(ref BallState ballState, ref FlipperCorrec // Polarity Correction bool isLeft = angleEnd < angleStart; // TODO: better if not classic flippers (trigonometry problems) - float AddX = LinearEnvelopeEven(ballPos, ref polarities, 0F); + float AddX = LinearEnvelopeEven(ballPos, flipperCorrectionState.Polarities, 0F); if(!isLeft) { AddX = -AddX; } @@ -96,7 +93,7 @@ private static float PSlope(float x, float x1, float y1, float x2, float y2) // return m * x + b; } - private static float LinearEnvelope(float xInput, ref BlobArray curve, float defaultValue = 1F) + private static float LinearEnvelope(float xInput, ref UnmanagedArray curve, float defaultValue = 1F) { if (curve.Length <= 0) return defaultValue; @@ -126,7 +123,7 @@ private static float LinearEnvelope(float xInput, ref BlobArray curve, f } // if segments are even on x axis, no need to iterate: faster - private static float LinearEnvelopeEven(float xInput, ref BlobArray curve, float defaultValue = 1F) + private static float LinearEnvelopeEven(float xInput, UnmanagedArray curve, float defaultValue = 1F) { if (curve.Length <= 0) return defaultValue; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs deleted file mode 100644 index b902934be..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Visual Pinball Engine -// Copyright (C) 2023 freezy and VPE Team -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using Unity.Entities; -using Unity.Mathematics; - -namespace VisualPinball.Unity -{ - public struct FlipperCorrectionBlob - { - public int FlipperItemId; - public BlobArray Polarities; - public BlobArray Velocities; - public uint TimeDelayMs; - } -} diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs.meta b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs.meta deleted file mode 100644 index 692af5c11..000000000 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionBlob.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a385a32de1a35664899367786c93a093 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs index 723096bed..d204fe68e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs @@ -14,13 +14,60 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; +using System; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Mathematics; namespace VisualPinball.Unity { - public struct FlipperCorrectionState + public unsafe struct FlipperCorrectionState : IDisposable { - public bool IsEnabled; - public BlobAssetReference Value; + public readonly bool IsEnabled; + public readonly int FlipperItemId; + public readonly uint TimeDelayMs; + + [NativeDisableUnsafePtrRestriction] private void* _polarities; + [NativeDisableUnsafePtrRestriction] private void* _velocities; + + private readonly int _numPolarities; + private readonly int _numVelocities; + + private readonly Allocator _allocator; + + public FlipperCorrectionState(bool isEnabled, int flipperItemId, uint timeDelayMs, float2[] polarities, float2[] velocities, Allocator allocator) + { + IsEnabled = isEnabled; + FlipperItemId = flipperItemId; + TimeDelayMs = timeDelayMs; + _polarities = Allocate(polarities, allocator); + _velocities = Allocate(velocities, allocator); + _allocator = allocator; + _numPolarities = polarities.Length; + _numVelocities = velocities.Length; + } + + public UnmanagedArray Velocities => new(_velocities, _numVelocities); + public UnmanagedArray Polarities => new(_polarities, _numPolarities); + + private static void* Allocate(float2[] src, Allocator allocator) + { + var na = new NativeArray(src, Allocator.Temp); + var size = UnsafeUtility.SizeOf() * src.Length; + var dest = UnsafeUtility.Malloc(size, UnsafeUtility.AlignOf(), allocator); + UnsafeUtility.MemCpy(dest, na.GetUnsafeReadOnlyPtr(), size); + na.Dispose(); + + return dest; + } + + public void Dispose() + { + UnsafeUtility.Free(_velocities, _allocator); + UnsafeUtility.Free(_polarities, _allocator); + + _polarities = null; + _velocities = null; + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs index f522039f6..28bda1dcd 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateCollider.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; namespace VisualPinball.Unity @@ -50,17 +48,6 @@ public GateCollider(in LineCollider lineSeg0, in LineCollider lineSeg1, Collider Bounds = LineSeg0.Bounds; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(GateCollider) - ); - } - #region Narrowphase public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallState ball, float dTime) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/IMainRenderableComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/IMainRenderableComponent.cs index 75c526700..7eb40db1f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/IMainRenderableComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/IMainRenderableComponent.cs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Unity.Entities; using UnityEngine; namespace VisualPinball.Unity @@ -55,7 +54,6 @@ public interface IMainRenderableComponent : IMainComponent void SetEditorRotation(Vector3 pos); ItemDataTransformType EditorScaleType { get; } - Entity Entity { get; set; } Vector3 GetEditorScale(); void SetEditorScale(Vector3 pos); void EditorStartScaling(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs index 4a9e0c905..be4eb268a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs @@ -123,11 +123,11 @@ private static void DoChangeBallVelocity(ref BallState ball, in float3 hitNormal { var minDistSqr = Constants.FloatMax; var idx = 0u; - ref var hitMesh = ref meshData.Value.Value.Vertices; - ref var hitMeshNormals = ref meshData.Value.Value.Normals; + var hitMesh = meshData.Vertices; + var hitMeshNormals = meshData.Normals; for (var t = 0; t < hitMesh.Length; t++) { // find the right normal by calculating the distance from current ball position to vertex of the kicker mesh - ref var vertex = ref hitMesh[t]; + ref var vertex = ref hitMesh.GetAsRef(t); var lengthSqr = math.lengthsq(ball.Position - vertex); if (lengthSqr < minDistSqr) { minDistSqr = lengthSqr; @@ -138,7 +138,7 @@ private static void DoChangeBallVelocity(ref BallState ball, in float3 hitNormal if (idx != ~0u) { // we have the nearest vertex now use the normal and damp it so it doesn't speed up the ball velocity too much - ref var hitNorm = ref hitMeshNormals[(int)idx]; + ref var hitNorm = ref hitMeshNormals.GetAsRef((int)idx); var dot = -math.dot(ball.Velocity, hitNorm); var reactionImpulse = ball.Mass * math.abs(dot); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderMeshData.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderMeshData.cs index 6c7807049..01b0169f6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderMeshData.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderMeshData.cs @@ -14,40 +14,57 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; using System.Collections.Generic; using Unity.Collections; -using Unity.Entities; +using Unity.Collections.LowLevel.Unsafe; using Unity.Mathematics; using VisualPinball.Engine.Math; namespace VisualPinball.Unity { - public struct KickerMeshVertexBlobAsset - { - public BlobArray Vertices; - public BlobArray Normals; - } - internal struct ColliderMeshData + internal unsafe struct ColliderMeshData : IDisposable { - public BlobAssetReference Value; + [NativeDisableUnsafePtrRestriction] private void* _vertices; + [NativeDisableUnsafePtrRestriction] private void* _normals; + + private readonly int _length; - public ColliderMeshData(IList vertices, float radius, float3 position) + private readonly Allocator _allocator; + + public ColliderMeshData(IList vertices, float radius, float3 position, Allocator allocator) { var rad = radius * 0.8f; - using var blobBuilder = new BlobBuilder(Allocator.Temp); - ref var blobAsset = ref blobBuilder.ConstructRoot(); - var blobVertices = blobBuilder.Allocate(ref blobAsset.Vertices, vertices.Count); - var blobNormals = blobBuilder.Allocate(ref blobAsset.Normals, vertices.Count); + _length = UnsafeUtility.SizeOf() * vertices.Count; + _vertices = UnsafeUtility.Malloc(_length, UnsafeUtility.AlignOf(), allocator); + _normals = UnsafeUtility.Malloc(_length, UnsafeUtility.AlignOf(), allocator); + for (var i = 0; i < vertices.Count; i++) { - blobVertices[i] = new float3( + UnsafeUtility.WriteArrayElement(_vertices, i, new float3( vertices[i].X * rad + position.x, vertices[i].Y * rad + position.y, vertices[i].Z * rad + position.z - ); - blobNormals[i] = new float3(vertices[i].Nx, vertices[i].Ny, vertices[i].Nz); + )); + UnsafeUtility.WriteArrayElement(_normals, i, new float3( + vertices[i].Nx, + vertices[i].Ny, + vertices[i].Nz + )); } - Value = blobBuilder.CreateBlobAssetReference(Allocator.Persistent); + _allocator = allocator; + } + + public UnmanagedArray Vertices => new(_vertices, _length); + public UnmanagedArray Normals => new(_normals, _length); + + public void Dispose() + { + UnsafeUtility.Free(_vertices, _allocator); + UnsafeUtility.Free(_normals, _allocator); + + _vertices = null; + _normals = null; } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs index ea52202a8..2716db74b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs @@ -25,6 +25,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using Unity.Collections; using Unity.Mathematics; using UnityEditor; using UnityEngine; @@ -276,8 +277,8 @@ internal KickerState CreateState() var height = SurfaceHeight(Surface, Position); var meshData = colliderComponent.LegacyMode - ? new ColliderMeshData(Array.Empty(), 0, float3.zero) - : new ColliderMeshData(KickerHitMesh.Vertices, Radius, new float3(Center.x, Center.y, height)); + ? new ColliderMeshData(Array.Empty(), 0, float3.zero, Allocator.Persistent) + : new ColliderMeshData(KickerHitMesh.Vertices, Radius, new float3(Center.x, Center.y, height), Allocator.Persistent); return new KickerState( colliderComponent ? colliderComponent.gameObject.GetInstanceID() : 0, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs index 21c3133d2..c18df1806 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerState.cs @@ -14,9 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; + namespace VisualPinball.Unity { - internal struct KickerState + internal struct KickerState : IDisposable { internal readonly int ItemId; internal KickerStaticState Static; @@ -30,5 +32,10 @@ public KickerState(int itemId, KickerStaticState @static, KickerCollisionState c Collision = collision; CollisionMesh = collisionMesh; } + + public void Dispose() + { + CollisionMesh.Dispose(); + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs index 1fe501f77..b13f99eb4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MainRenderableComponent.cs @@ -17,7 +17,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Unity.Entities; using UnityEngine; using VisualPinball.Engine.Math; using VisualPinball.Engine.VPT; @@ -44,8 +43,6 @@ public abstract class MainRenderableComponent : MainComponent, protected abstract Type ColliderComponentType { get; } - public Entity Entity { get; set; } - /// /// Returns all child mesh components linked to this data. /// @@ -102,11 +99,6 @@ public virtual void UpdateVisibility() { } - protected void Convert(Entity entity, EntityManager dstManager) - { - Entity = entity; - } - protected float SurfaceHeight(ISurfaceComponent surface, Vector2 position) { return surface?.Height(position) ?? PlayfieldHeight; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs index 5c64ebed6..affdc6999 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/RotatorComponent.cs @@ -18,7 +18,6 @@ using System.Collections.Generic; using System.Linq; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; @@ -59,7 +58,6 @@ public IRotatableComponent[] RotateWith { private (KickerApi kicker, float distance, float angle, int ballId)[] _balls; private Dictionary _rotatingObjectDistances = new(); - private static EntityManager EntityManager => World.DefaultGameObjectInjectionWorld.EntityManager; private void Awake() { diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs index 6d45277d5..0300ede24 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerCollider.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; using VisualPinball.Engine.VPT.Plunger; @@ -69,17 +67,6 @@ public PlungerCollider(PlungerComponent comp, PlungerColliderComponent collComp, )); } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(PlungerCollider) - ); - } - #region Narrowphase public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs index e9bea4d0d..05f57fad2 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerCollider.cs @@ -15,8 +15,6 @@ // along with this program. If not, see . using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; -using Unity.Entities; using Unity.Mathematics; using VisualPinball.Engine.Common; @@ -67,17 +65,6 @@ public SpinnerCollider(SpinnerComponent component, float height, ColliderInfo in Bounds = LineSeg0.Bounds; } - public unsafe void Allocate(BlobBuilder builder, ref BlobBuilderArray> colliders) - { - ref var ptr = ref UnsafeUtility.As, BlobPtr>(ref colliders[Header.Id]); - ref var collider = ref builder.Allocate(ref ptr); - UnsafeUtility.MemCpy( - UnsafeUtility.AddressOf(ref collider), - UnsafeUtility.AddressOf(ref this), - sizeof(SpinnerCollider) - ); - } - #region Narrowphase public float HitTest(ref CollisionEventData collEvent, ref InsideOfs insideOfs, in BallState ball, float dTime) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotComponent.cs index bb711442a..459aa4f92 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotComponent.cs @@ -19,7 +19,6 @@ using System; using System.Collections; using System.Collections.Generic; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using UnityEngine.Serialization; @@ -241,7 +240,6 @@ private Mesh GetMesh() public bool CanBeTransformed => false; public bool OverrideTransform => false; public string ItemName => "Slingshot"; - public Entity Entity { get; set; } public void UpdateTransforms() { } public void UpdateVisibility() { } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs index a99a80960..afef30824 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs @@ -25,7 +25,6 @@ using System.Collections.Generic; using System.Linq; using Unity.Collections; -using Unity.Entities; using Unity.Mathematics; using UnityEngine; using VisualPinball.Engine.Game.Engines; @@ -271,25 +270,6 @@ internal TriggerState CreateState() ); } - // flipper correction trigger has additional data - using var builder = new BlobBuilder(Allocator.Temp); - ref var root = ref builder.ConstructRoot(); - - root.FlipperItemId = collComponent.ForFlipper.gameObject.GetInstanceID(); - root.TimeDelayMs = collComponent.TimeThresholdMs; - - var polarities = builder.Allocate(ref root.Polarities, collComponent.FlipperPolarities.Length); - for (var i = 0; i < collComponent.FlipperPolarities.Length; i++) { - polarities[i] = collComponent.FlipperPolarities[i]; - } - - var velocities = builder.Allocate(ref root.Velocities, collComponent.FlipperVelocities.Length); - for (var i = 0; i < collComponent.FlipperVelocities.Length; i++) { - velocities[i] = collComponent.FlipperVelocities[i]; - } - - var blobAssetRef = builder.CreateBlobAssetReference(Allocator.Persistent); - return new TriggerState( gameObject.GetInstanceID(), new TriggerStaticState { @@ -298,10 +278,14 @@ internal TriggerState CreateState() Shape = TriggerShape.TriggerNone, TableScaleZ = 1f }, - new FlipperCorrectionState { - IsEnabled = true, - Value = blobAssetRef - } + new FlipperCorrectionState( + true, + collComponent.ForFlipper.gameObject.GetInstanceID(), + collComponent.TimeThresholdMs, + collComponent.FlipperPolarities, + collComponent.FlipperVelocities, + Allocator.Persistent + ) ); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs index afa9e8289..ef9acff93 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerState.cs @@ -14,9 +14,11 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +using System; + namespace VisualPinball.Unity { - internal struct TriggerState + internal struct TriggerState : IDisposable { internal readonly int ItemId; internal readonly int AnimatedItemId; @@ -50,5 +52,10 @@ public TriggerState(int itemId, TriggerStaticState @static, FlipperCorrectionSta Animation = default; FlipperCorrection = flipperCorrection; } + + public void Dispose() + { + FlipperCorrection.Dispose(); + } } } diff --git a/package.json b/package.json index db2a575cf..e198c011e 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "unity": "2021.3", "unityRelease": "0f1", "dependencies": { - "com.unity.entities": "1.0.16", "com.bartofzo.nativetrees": "0.1.6", "com.unity.formats.fbx": "4.1.2", "com.unity.inputsystem": "1.3.0", From 347b1a0dc9401b866c2c149e005bd549fc03d758 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 29 Oct 2023 01:46:37 +0200 Subject: [PATCH 155/159] jobs: Properly dispose physics state. --- .../Collections/UnmanagedArray.cs | 9 +++++ .../VisualPinball.Unity/Game/PhysicsEngine.cs | 22 +++++++++++++ .../VisualPinball.Unity/Game/PhysicsState.cs | 33 +------------------ .../VPT/Flipper/FlipperCorrectionState.cs | 8 ++--- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs b/VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs index 8e5d28c30..8fac3f300 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Collections/UnmanagedArray.cs @@ -53,5 +53,14 @@ public ref T GetAsRef(int index) } return ref UnsafeUtility.ArrayElementAsRef(_buffer, index); } + + public T[] ToArray() + { + var array = new T[Length]; + for (var i = 0; i < Length; i++) { + array[i] = UnsafeUtility.ReadArrayElement(_buffer, i); + } + return array; + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index d37daa8a0..b53b59c72 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -376,6 +376,28 @@ private void OnDestroy() _ballStates.Dispose(); _colliders.Dispose(); _insideOfs.Dispose(); + _octree.Dispose(); + _bumperStates.Dispose(); + _dropTargetStates.Dispose(); + _flipperStates.Dispose(); + _gateStates.Dispose(); + _hitTargetStates.Dispose(); + using (var enumerator = _kickerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + enumerator.Current.Value.Dispose(); + } + } + _kickerStates.Dispose(); + _plungerStates.Dispose(); + _spinnerStates.Dispose(); + _surfaceStates.Dispose(); + using (var enumerator = _triggerStates.GetEnumerator()) { + while (enumerator.MoveNext()) { + enumerator.Current.Value.Dispose(); + } + } + _triggerStates.Dispose(); + _disabledCollisionItems.Dispose(); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs index e8e36e0e6..996d8072f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs @@ -14,7 +14,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System; using NativeTrees; using Unity.Collections; using VisualPinball.Engine.VPT; @@ -22,7 +21,7 @@ namespace VisualPinball.Unity { - internal struct PhysicsState : IDisposable + internal struct PhysicsState { internal PhysicsEnv Env; internal NativeOctree Octree; @@ -184,35 +183,5 @@ private bool IsInactiveDropTarget(int colliderId) } #endregion - - public void Dispose() - { - Env.Dispose(); - Octree.Dispose(); - Colliders.Dispose(); - InsideOfs.Dispose(); - Balls.Dispose(); - BumperStates.Dispose(); - DropTargetStates.Dispose(); - FlipperStates.Dispose(); - GateStates.Dispose(); - HitTargetStates.Dispose(); - using (var enumerator = KickerStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - enumerator.Current.Value.Dispose(); - } - } - KickerStates.Dispose(); - PlungerStates.Dispose(); - SpinnerStates.Dispose(); - SurfaceStates.Dispose(); - using (var enumerator = TriggerStates.GetEnumerator()) { - while (enumerator.MoveNext()) { - enumerator.Current.Value.Dispose(); - } - } - TriggerStates.Dispose(); - DisabledCollisionItems.Dispose(); - } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs index d204fe68e..64b8e801b 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs @@ -40,9 +40,9 @@ public FlipperCorrectionState(bool isEnabled, int flipperItemId, uint timeDelayM IsEnabled = isEnabled; FlipperItemId = flipperItemId; TimeDelayMs = timeDelayMs; - _polarities = Allocate(polarities, allocator); - _velocities = Allocate(velocities, allocator); _allocator = allocator; + _polarities = Allocate(polarities, _allocator); + _velocities = Allocate(velocities, _allocator); _numPolarities = polarities.Length; _numVelocities = velocities.Length; } @@ -63,8 +63,8 @@ public FlipperCorrectionState(bool isEnabled, int flipperItemId, uint timeDelayM public void Dispose() { - UnsafeUtility.Free(_velocities, _allocator); - UnsafeUtility.Free(_polarities, _allocator); + UnsafeUtility.Free(_velocities, Allocator.None); + UnsafeUtility.Free(_polarities, Allocator.Temp); _polarities = null; _velocities = null; From def9de2b886075346caca50ec33d259c9ba390da Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 29 Oct 2023 09:13:46 +0100 Subject: [PATCH 156/159] doc: Update Unity version. --- .../creators-guide/setup/installing-vpe.md | 9 ++------- .../VPT/Flipper/FlipperCorrectionState.cs | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/VisualPinball.Unity/Documentation~/creators-guide/setup/installing-vpe.md b/VisualPinball.Unity/Documentation~/creators-guide/setup/installing-vpe.md index 6087321fa..23a22fb7a 100644 --- a/VisualPinball.Unity/Documentation~/creators-guide/setup/installing-vpe.md +++ b/VisualPinball.Unity/Documentation~/creators-guide/setup/installing-vpe.md @@ -13,16 +13,11 @@ In order to start creating or modifying tables with VPE, the first thing you'll Unity uses an application called *Unity Hub* to update itself, create new projects and provide quick access to them. The install process is straight-forward and documented [here](https://docs.unity3d.com/Manual/GettingStartedInstallingHub.html) if you run into troubles. -**2021.3.0** is the latest version supported by VPE so click on *Skip Installation* in the first dialog to avoid installing the newest version of the Editor. After accepting the license agreement you will have access to Unity Hub. - -> [!NOTE] -> To install the supported version of the editor you can either -> * Paste this direct link into your browser: unityhub://2021.3.0f1/6eacc8284459 -> * Find the correct version from the [Unity release archive](https://unity3d.com/get-unity/download/archive) +**2022.3** is the recommended Unity version at the moment. Once 2023 is officially out, we'll be updating the dependencies and the documentation. You can leave all the other options unchecked during install. -Once Unity is downloaded and installed, you're ready to create a new VPE project. Click on *New Project*, be sure to have selected the 2021.3.0f1 version at the top, and you'll see the following choices: +Once Unity is downloaded and installed, you're ready to create a new VPE project. Click on *New Project*, be sure to have selected the 2022.3 version at the top, and you'll see the following choices: ![New Unity Project](unity-create-new-project.png) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs index 64b8e801b..7c2b939a6 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperCorrectionState.cs @@ -64,7 +64,7 @@ public FlipperCorrectionState(bool isEnabled, int flipperItemId, uint timeDelayM public void Dispose() { UnsafeUtility.Free(_velocities, Allocator.None); - UnsafeUtility.Free(_polarities, Allocator.Temp); + UnsafeUtility.Free(_polarities, Allocator.None); _polarities = null; _velocities = null; From ef6e14ce4af58b0b7c6d2bd344b9fa127446ecc3 Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 29 Oct 2023 20:18:59 +0100 Subject: [PATCH 157/159] fix: A few physics tweaks. --- VisualPinball.Engine/Common/Constants.cs | 4 +- .../VisualPinball.Unity/Game/PhysicsCycle.cs | 2 +- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 3 +- .../Physics/Collider/ColliderReference.cs | 36 +++++++++----- .../Physics/Collider/PlaneCollider.cs | 6 +-- .../Physics/NativeCollider.cs | 48 +++++++++---------- .../VPT/Ball/BallComponent.cs | 29 ++++++----- .../VPT/Ball/BallManager.cs | 8 ++-- 8 files changed, 77 insertions(+), 59 deletions(-) diff --git a/VisualPinball.Engine/Common/Constants.cs b/VisualPinball.Engine/Common/Constants.cs index a9fca5a72..4bb1623e1 100644 --- a/VisualPinball.Engine/Common/Constants.cs +++ b/VisualPinball.Engine/Common/Constants.cs @@ -86,10 +86,12 @@ public static class PhysicsConstants public const float DefaultTableMaxSlope = 6.0f; // DEFAULT_TABLE_MAX_SLOPE public const float DefaultTableGravity = 0.97f; // DEFAULT_TABLE_GRAVITY + public const float GravityConst = 1.81751f; // GRAVITYCONST + /// /// trigger/kicker boundary crossing hysterisis /// - public const float StaticTime = 0.005f; // STATICTIME + public const float StaticTime = 0.02f; // STATICTIME public const float StaticCnts = 10f; // STATICCNTS /// diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs index c91c1d8f6..b179cdaee 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsCycle.cs @@ -165,7 +165,7 @@ private static void ApplyStaticTime(ref float hitTime, ref float staticCounts, i var collEvent = ball.CollisionEvent; if (collEvent.HasCollider() && collEvent.HitTime <= hitTime) { // smaller hit time?? hitTime = collEvent.HitTime; // record actual event time - if (collEvent.HitTime < PhysicsConstants.StaticTime) { // less than static time interval + if (hitTime < PhysicsConstants.StaticTime) { // less than static time interval if (--staticCounts < 0) { staticCounts = 0; // keep from wrapping hitTime = PhysicsConstants.StaticTime; diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index b53b59c72..f4258de73 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -23,6 +23,7 @@ using Unity.Jobs; using Unity.Mathematics; using UnityEngine; +using VisualPinball.Engine.Common; using VisualPinball.Unity.Collections; using AABB = NativeTrees.AABB; using Debug = UnityEngine.Debug; @@ -34,7 +35,7 @@ public class PhysicsEngine : MonoBehaviour #region Configuration [Tooltip("Gravity constant, in VPX units.")] - public float GravityStrength = 1.762985f; + public float GravityStrength = PhysicsConstants.GravityConst * PhysicsConstants.DefaultTableGravity; #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs index dcd31ce9d..29e1bc729 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs @@ -100,88 +100,100 @@ private ICollider LookupCollider(int i) #region Add - internal void Add(CircleCollider collider) + internal int Add(CircleCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Circle, CircleColliders.Length)); CircleColliders.Add(collider); + return collider.Id; } - internal void Add(FlipperCollider collider) + internal int Add(FlipperCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Flipper, FlipperColliders.Length)); FlipperColliders.Add(collider); + return collider.Id; } - internal void Add(GateCollider collider) + internal int Add(GateCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Gate, GateColliders.Length)); GateColliders.Add(collider); + return collider.Id; } - internal void Add(Line3DCollider collider) + internal int Add(Line3DCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Line3D, Line3DColliders.Length)); Line3DColliders.Add(collider); + return collider.Id; } - internal void Add(LineSlingshotCollider collider) + internal int Add(LineSlingshotCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.LineSlingShot, LineSlingshotColliders.Length)); LineSlingshotColliders.Add(collider); + return collider.Id; } - internal void Add(LineCollider collider) + internal int Add(LineCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Line, LineColliders.Length)); LineColliders.Add(collider); + return collider.Id; } - internal void Add(LineZCollider collider) + internal int Add(LineZCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.LineZ, LineZColliders.Length)); LineZColliders.Add(collider); + return collider.Id; } - internal void Add(PlungerCollider collider) + internal int Add(PlungerCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Plunger, PlungerColliders.Length)); PlungerColliders.Add(collider); + return collider.Id; } - internal void Add(PointCollider collider) + internal int Add(PointCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Point, PointColliders.Length)); PointColliders.Add(collider); + return collider.Id; } - internal void Add(SpinnerCollider collider) + internal int Add(SpinnerCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Spinner, SpinnerColliders.Length)); SpinnerColliders.Add(collider); + return collider.Id; } - internal void Add(TriangleCollider collider) + internal int Add(TriangleCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Triangle, TriangleColliders.Length)); TriangleColliders.Add(collider); + return collider.Id; } - internal void Add(PlaneCollider collider) + internal int Add(PlaneCollider collider) { collider.Id = Lookup.Length; Lookup.Add(new ColliderLookup(ColliderType.Plane, PlaneColliders.Length)); PlaneColliders.Add(collider); + return collider.Id; } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs index 691a31615..7ff1a87ee 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/PlaneCollider.cs @@ -99,11 +99,7 @@ public float HitTest(ref CollisionEventData collEvent, in BallState ball, float collEvent.HitNormal = _normal; collEvent.HitDistance = bnd; // actual contact distance - - if (collEvent.HitNormal is { x: 0, y: 0, z: 0 }) { - Debug.Log("Hit normal set to zero by plane collider."); - } - + return hitTime; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs index 478c3ac3e..73e628c51 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Physics/NativeCollider.cs @@ -150,9 +150,9 @@ public NativeColliders(ref ColliderReference colRef, Allocator allocator) #region Collider Access - internal ref CircleCollider Circle(int index) + internal ref CircleCollider Circle(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.Circle) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up circle collider."); @@ -161,9 +161,9 @@ internal ref CircleCollider Circle(int index) return ref UnsafeUtility.ArrayElementAsRef(m_CircleColliderBuffer, lookup.Index); } - internal ref FlipperCollider Flipper(int index) + internal ref FlipperCollider Flipper(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.Flipper) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up flipper collider."); @@ -172,9 +172,9 @@ internal ref FlipperCollider Flipper(int index) return ref UnsafeUtility.ArrayElementAsRef(m_FlipperColliderBuffer, lookup.Index); } - internal ref GateCollider Gate(int index) + internal ref GateCollider Gate(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.Gate) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up gate collider."); @@ -183,9 +183,9 @@ internal ref GateCollider Gate(int index) return ref UnsafeUtility.ArrayElementAsRef(m_GateColliderBuffer, lookup.Index); } - internal ref Line3DCollider Line3D(int index) + internal ref Line3DCollider Line3D(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.Line3D) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up line3d collider."); @@ -194,9 +194,9 @@ internal ref Line3DCollider Line3D(int index) return ref UnsafeUtility.ArrayElementAsRef(m_Line3DColliderBuffer, lookup.Index); } - internal ref LineCollider Line(int index) + internal ref LineCollider Line(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.Line) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up line collider."); @@ -205,9 +205,9 @@ internal ref LineCollider Line(int index) return ref UnsafeUtility.ArrayElementAsRef(m_LineColliderBuffer, lookup.Index); } - internal ref LineSlingshotCollider LineSlingShot(int index) + internal ref LineSlingshotCollider LineSlingShot(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.LineSlingShot) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up line slingshot collider."); @@ -216,9 +216,9 @@ internal ref LineSlingshotCollider LineSlingShot(int index) return ref UnsafeUtility.ArrayElementAsRef(m_LineSlingshotColliderBuffer, lookup.Index); } - internal ref LineZCollider LineZ(int index) + internal ref LineZCollider LineZ(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.LineZ) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up line-z collider."); @@ -227,9 +227,9 @@ internal ref LineZCollider LineZ(int index) return ref UnsafeUtility.ArrayElementAsRef(m_LineZColliderBuffer, lookup.Index); } - internal ref PlaneCollider Plane(int index) + internal ref PlaneCollider Plane(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.Plane) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up plane collider."); @@ -238,9 +238,9 @@ internal ref PlaneCollider Plane(int index) return ref UnsafeUtility.ArrayElementAsRef(m_PlaneColliderBuffer, lookup.Index); } - internal ref PlungerCollider Plunger(int index) + internal ref PlungerCollider Plunger(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.Plunger) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up plunger collider."); @@ -249,9 +249,9 @@ internal ref PlungerCollider Plunger(int index) return ref UnsafeUtility.ArrayElementAsRef(m_PlungerColliderBuffer, lookup.Index); } - internal ref PointCollider Point(int index) + internal ref PointCollider Point(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.Point) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up point collider."); @@ -260,9 +260,9 @@ internal ref PointCollider Point(int index) return ref UnsafeUtility.ArrayElementAsRef(m_PointColliderBuffer, lookup.Index); } - internal ref SpinnerCollider Spinner(int index) + internal ref SpinnerCollider Spinner(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.Spinner) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up spinner collider."); @@ -271,9 +271,9 @@ internal ref SpinnerCollider Spinner(int index) return ref UnsafeUtility.ArrayElementAsRef(m_SpinnerColliderBuffer, lookup.Index); } - internal ref TriangleCollider Triangle(int index) + internal ref TriangleCollider Triangle(int colliderId) { - ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, index); + ref var lookup = ref UnsafeUtility.ArrayElementAsRef(m_LookupBuffer, colliderId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (lookup.Type != ColliderType.Triangle) { throw new ArgumentException($"Invalid collider type {lookup.Type} when looking up triangle collider."); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs index 986045f62..6a91da5ca 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallComponent.cs @@ -30,17 +30,22 @@ public class BallComponent : MonoBehaviour public bool IsFrozen; - internal BallState CreateState() => new BallState { - Id = Id, - IsFrozen = IsFrozen, - Position = transform.localPosition.TranslateToVpx(), - Radius = Radius, - Mass = Mass, - Velocity = Velocity, - BallOrientation = float3x3.identity, - BallOrientationForUnity = float3x3.identity, - RingCounterOldPos = 0, - AngularMomentum = float3.zero - }; + internal BallState CreateState() + { + var pos = transform.localPosition.TranslateToVpx(); + return new BallState + { + Id = Id, + IsFrozen = IsFrozen, + Position = new float3(pos.x, pos.y, math.round(pos.z*100000) / 100000), + Radius = Radius, + Mass = Mass, + Velocity = Velocity, + BallOrientation = float3x3.identity, + BallOrientationForUnity = float3x3.identity, + RingCounterOldPos = 0, + AngularMomentum = float3.zero + }; + } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index ee77df08a..8c10682ee 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -40,12 +40,12 @@ public BallManager(PhysicsEngine physicsEngine, Player player, Transform parent) _parent = parent; } - public void CreateBall(IBallCreationPosition ballCreator, float radius = 25f, float mass = 1f) + public int CreateBall(IBallCreationPosition ballCreator, float radius = 25f, float mass = 1f) { - CreateBall(ballCreator, radius, mass, 0); + return CreateBall(ballCreator, radius, mass, 0); } - public void CreateBall(IBallCreationPosition ballCreator, float radius, float mass, int kickerId, GameObject ballPrefab = null) + public int CreateBall(IBallCreationPosition ballCreator, float radius, float mass, int kickerId, GameObject ballPrefab = null) { var localPos = ballCreator.GetBallCreationPosition().ToUnityFloat3(); localPos.z += radius; @@ -77,6 +77,8 @@ public void CreateBall(IBallCreationPosition ballCreator, float radius, float ma kickerData.Collision.LastCapturedBallId = ballComp.Id; } } + + return ballComp.Id; } public void DestroyBall(int ballId) From 2d9ceb423cb8f64eac94cadf0edcdd268639273b Mon Sep 17 00:00:00 2001 From: freezy Date: Sun, 29 Oct 2023 22:18:30 +0100 Subject: [PATCH 158/159] player: Don't instantiate API instances twice. --- .../VisualPinball.Unity/Game/PhysicsEngine.cs | 5 +- .../Game/PhysicsStaticCollision.cs | 2 +- .../VisualPinball.Unity/Game/Player.cs | 129 +----------------- .../VPT/Bumper/BumperColliderComponent.cs | 2 +- .../VPT/Bumper/BumperComponent.cs | 11 +- .../CollisionSwitchComponent.cs | 7 +- .../DropTargetBank/DropTargetBankComponent.cs | 7 +- .../VPT/Flipper/FlipperColliderComponent.cs | 2 +- .../VPT/Flipper/FlipperComponent.cs | 17 ++- .../VPT/Gate/GateColliderComponent.cs | 2 +- .../VPT/Gate/GateComponent.cs | 11 +- .../VPT/Gate/GateLifterComponent.cs | 8 +- .../HitTarget/DropTargetColliderComponent.cs | 2 +- .../VPT/HitTarget/DropTargetComponent.cs | 11 +- .../HitTarget/HitTargetColliderComponent.cs | 2 +- .../VPT/HitTarget/HitTargetComponent.cs | 11 +- .../VisualPinball.Unity/VPT/ItemComponent.cs | 5 +- .../VPT/Kicker/KickerApi.cs | 19 ++- .../VPT/Kicker/KickerCollider.cs | 116 ++++++++-------- .../VPT/Kicker/KickerColliderComponent.cs | 4 +- .../VPT/Kicker/KickerComponent.cs | 19 +-- .../VPT/Light/LightComponent.cs | 2 +- .../VPT/Light/LightGroupComponent.cs | 2 +- .../VPT/Mech/ScoreMotorComponent.cs | 8 +- .../VPT/Mech/StepRotatorMechComponent.cs | 7 +- .../MetalWireGuideColliderComponent.cs | 2 +- .../MetalWireGuide/MetalWireGuideComponent.cs | 11 +- .../Playfield/PlayfieldColliderComponent.cs | 2 +- .../VPT/Playfield/PlayfieldComponent.cs | 12 +- .../VPT/Plunger/PlungerColliderComponent.cs | 2 +- .../VPT/Plunger/PlungerComponent.cs | 11 +- .../Primitive/PrimitiveColliderComponent.cs | 2 +- .../VPT/Primitive/PrimitiveComponent.cs | 11 +- .../VPT/Ramp/RampColliderComponent.cs | 2 +- .../VPT/Ramp/RampComponent.cs | 11 +- .../VPT/Rubber/RubberColliderComponent.cs | 2 +- .../VPT/Rubber/RubberComponent.cs | 11 +- .../VPT/Spinner/SpinnerColliderComponent.cs | 2 +- .../VPT/Spinner/SpinnerComponent.cs | 11 +- .../VPT/Surface/SlingshotComponent.cs | 9 +- .../VPT/Surface/SurfaceColliderComponent.cs | 2 +- .../VPT/Surface/SurfaceComponent.cs | 11 +- .../VPT/Teleporter/TeleporterComponent.cs | 7 +- .../VPT/Trigger/TriggerColliderComponent.cs | 2 +- .../VPT/Trigger/TriggerComponent.cs | 10 +- .../VPT/Trough/TroughComponent.cs | 7 +- 46 files changed, 279 insertions(+), 272 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs index f4258de73..b6fb6007c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs @@ -91,8 +91,11 @@ public void ScheduleAction(uint timeoutMs, Action action) internal delegate void InputAction(ref PhysicsState state); internal ref NativeParallelHashMap Balls => ref _ballStates; + internal ref InsideOfs InsideOfs => ref _insideOfs; + internal NativeQueue.ParallelWriter EventQueue => _eventQueue.AsParallelWriter(); + internal void Schedule(InputAction action) => _inputActions.Enqueue(action); - internal ref BallState BallState(int itemId) => ref _ballStates.GetValueByRef(itemId); + internal ref BallState BallState(int ballId) => ref _ballStates.GetValueByRef(ballId); internal ref BumperState BumperState(int itemId) => ref _bumperStates.GetValueByRef(itemId); internal ref FlipperState FlipperState(int itemId) => ref _flipperStates.GetValueByRef(itemId); internal ref GateState GateState(int itemId) => ref _gateStates.GetValueByRef(itemId); diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs index e4aa7f32d..1fa4ae3e7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs @@ -123,7 +123,7 @@ private static void Collide(ref BallState ball, ref PhysicsState state) case ColliderType.KickerCircle: ref var kickerState = ref state.GetKickerState(colliderId); KickerCollider.Collide(ref ball, ref state.EventQueue, ref state.InsideOfs, ref kickerState.Collision, - in kickerState.Static, in kickerState.CollisionMesh, in ball.CollisionEvent, collHeader.ItemId); + in kickerState.Static, in kickerState.CollisionMesh, in ball.CollisionEvent, collHeader.ItemId, false); break; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index e8548627a..e57523cf8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -201,143 +201,26 @@ private void OnDestroy() } } -#endregion + #endregion #region Registrations - public void RegisterBumper(BumperComponent component) - { - Register(new BumperApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterFlipper(FlipperComponent component) - { - Register(new FlipperApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterDropTarget(DropTargetComponent component) - { - Register(new DropTargetApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterGate(GateComponent component) - { - Register(new GateApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterGateLifter(GateLifterComponent component) - { - Register(new GateLifterApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterHitTarget(HitTargetComponent component) - { - Register(new HitTargetApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterKicker(KickerComponent component) - { - Register(new KickerApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterLamp(LightComponent component) - { - Register(component.GetApi(this), component); - } - - public void RegisterLampGroup(LightGroupComponent component) - { - Register(component.GetApi(this), component); - } - - public void RegisterStepRotator(StepRotatorMechComponent component) + public void Register(PlungerApi plungerApi, PlungerComponent component, InputActionReference actionRef) { - Register(new StepRotatorMechApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterScoreMotorComponent(ScoreMotorComponent component) - { - Register(new ScoreMotorApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterDropTargetBankComponent(DropTargetBankComponent component) - { - Register(new DropTargetBankApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterCollisionSwitchComponent(CollisionSwitchComponent component) - { - Register(new CollisionSwitchApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterSlingshotComponent(SlingshotComponent component) - { - Register(new SlingshotApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterPlunger(PlungerComponent component, InputActionReference actionRef) - { - var plungerApi = new PlungerApi(component.gameObject, this, PhysicsEngine); Register(plungerApi, component); - if (actionRef != null) { actionRef.action.performed += plungerApi.OnAnalogPlunge; _actions.Add((actionRef.action, plungerApi.OnAnalogPlunge)); } } - public void RegisterPlayfield(GameObject go) - { - PlayfieldApi = new PlayfieldApi(go, this, PhysicsEngine); - _colliderGenerators.Add(PlayfieldApi); - } - - public void RegisterPrimitive(PrimitiveComponent component) - { - Register(new PrimitiveApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterRamp(RampComponent component) - { - Register(new RampApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterRubber(RubberComponent component) - { - Register(new RubberApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterSpinner(SpinnerComponent component) - { - Register(new SpinnerApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterSurface(SurfaceComponent component) - { - Register(new SurfaceApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterTeleporter(TeleporterComponent component) - { - Register(new TeleporterApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterTrigger(TriggerComponent component) - { - Register(new TriggerApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterTrough(TroughComponent component) - { - Register(new TroughApi(component.gameObject, this, PhysicsEngine), component); - } - - public void RegisterMetalWireGuide(MetalWireGuideComponent component) + public void Register(PlayfieldApi playfieldApi) { - Register(new MetalWireGuideApi(component.gameObject, this, PhysicsEngine), component); + PlayfieldApi = playfieldApi; + _colliderGenerators.Add(playfieldApi); } - private void Register(TApi api, MonoBehaviour component) where TApi : IApi + public void Register(TApi api, MonoBehaviour component) where TApi : IApi { TableApi.Register(component, api); _apis.Add(api); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs index 4fe40be3a..a3f19df37 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs @@ -44,7 +44,7 @@ public class BumperColliderComponent : ColliderComponent new BumperApi(gameObject, player, physicsEngine); + => MainComponent.BumperApi ?? new BumperApi(gameObject, player, physicsEngine); public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(scatterAngleDeg: Scatter); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs index 1ad472744..c71ece42a 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs @@ -85,12 +85,17 @@ public class BumperComponent : MainRenderableComponent, #region Runtime + public BumperApi BumperApi { get; private set; } + private void Awake() { - // register at player - GetComponentInParent().RegisterBumper(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + BumperApi = new BumperApi(gameObject, player, physicsEngine); + + player.Register(BumperApi, this); if (GetComponentInChildren()) { - RegisterPhysics(); + RegisterPhysics(physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchComponent.cs index 882c99989..0eebc8fcc 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/CollisionSwitch/CollisionSwitchComponent.cs @@ -37,9 +37,14 @@ public class CollisionSwitchComponent : MonoBehaviour, ISwitchDeviceComponent #region Runtime + public CollisionSwitchApi CollisionSwitchApi { get; private set; } + private void Awake() { - GetComponentInParent().RegisterCollisionSwitchComponent(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + CollisionSwitchApi = new CollisionSwitchApi(gameObject, player, physicsEngine); + player.Register(CollisionSwitchApi, this); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/DropTargetBank/DropTargetBankComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/DropTargetBank/DropTargetBankComponent.cs index 73f7e40fc..b030c0a8e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/DropTargetBank/DropTargetBankComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/DropTargetBank/DropTargetBankComponent.cs @@ -60,9 +60,14 @@ public class DropTargetBankComponent : MonoBehaviour, ICoilDeviceComponent, ISwi #region Runtime + public DropTargetBankApi DropTargetBankApi { get; private set; } + private void Awake() { - GetComponentInParent().RegisterDropTargetBankComponent(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + DropTargetBankApi = new DropTargetBankApi(gameObject, player, physicsEngine); + player.Register(DropTargetBankApi, this); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs index 1f0f1b06a..1a23f397d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperColliderComponent.cs @@ -159,6 +159,6 @@ public class FlipperColliderComponent : ColliderComponent new FlipperApi(gameObject, player, physicsEngine); + => MainComponent.FlipperApi ?? new FlipperApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs index 71a02498f..8c34e45ed 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Flipper/FlipperComponent.cs @@ -476,11 +476,17 @@ public List GetEnclosingPolygon(float margin = 0.0F, float stepSize = 5 #region Runtime + public FlipperApi FlipperApi { get; private set; } + private void Awake() { _originalRotateZ = _startAngle; - GetComponentInParent().RegisterFlipper(this); - RegisterPhysics(); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + FlipperApi = new FlipperApi(gameObject, player, physicsEngine); + + player.Register(FlipperApi, this); + RegisterPhysics(physicsEngine); } private void Start() @@ -707,8 +713,11 @@ private void SetupFlipperCorrection(FlipperColliderComponent colliderComponent) triggerCollider.FlipperVelocities = velocities; // need to explicitly register, since awake was called before the components were added. - GetComponentInParent().Register(triggerComponent); - GetComponentInParent().RegisterTrigger(triggerComponent); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + triggerComponent.TriggerApi = new TriggerApi(triggerComponent.gameObject, player, physicsEngine); + player.Register(triggerComponent.TriggerApi, triggerComponent); + physicsEngine.Register(triggerComponent); } private static void Discretize(AnimationCurve curve, IList outArray) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs index 7e1e85ef3..ef8bd0d53 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateColliderComponent.cs @@ -67,6 +67,6 @@ public class GateColliderComponent : ColliderComponent, public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(Elasticity, friction: Friction); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new GateApi(gameObject, player, physicsEngine); + => MainComponent.GateApi ?? new GateApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs index 401a6918a..53d9e21b7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateComponent.cs @@ -107,12 +107,17 @@ public bool ShowBracket { get { #region Runtime + public GateApi GateApi { get; private set; } + private void Awake() { - // register at player - GetComponentInParent().RegisterGate(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + GateApi = new GateApi(gameObject, player, physicsEngine); + + player.Register(GateApi, this); if (GetComponent()) { - RegisterPhysics(); + RegisterPhysics(physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateLifterComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateLifterComponent.cs index bb7d970f0..53991eb86 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateLifterComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Gate/GateLifterComponent.cs @@ -49,9 +49,15 @@ public class GateLifterComponent : MonoBehaviour, ICoilDeviceComponent #endregion + public GateLifterApi GateLifterApi { get; private set; } + private void Awake() { - GetComponentInParent().RegisterGateLifter(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + GateLifterApi = new GateLifterApi(gameObject, player, physicsEngine); + + player.Register(GateLifterApi, this); } } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs index 3177dd3f0..bda149905 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetColliderComponent.cs @@ -61,6 +61,6 @@ public class DropTargetColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new DropTargetApi(gameObject, player, physicsEngine); + => (MainComponent as DropTargetComponent)?.DropTargetApi ?? new DropTargetApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs index 443033a30..03ac170e3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/DropTargetComponent.cs @@ -130,12 +130,17 @@ public override HitTargetData CopyDataTo(HitTargetData data, string[] materialNa #region Runtime + public DropTargetApi DropTargetApi { get; private set; } + private void Awake() { - // register at player - GetComponentInParent().RegisterDropTarget(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + DropTargetApi = new DropTargetApi(gameObject, player, physicsEngine); + + player.Register(DropTargetApi, this); if (GetComponent() && GetComponentInChildren()) { - RegisterPhysics(); + RegisterPhysics(physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs index a773e3104..75d9bcf5f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetColliderComponent.cs @@ -55,6 +55,6 @@ public class HitTargetColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new HitTargetApi(gameObject, player, physicsEngine); + => (MainComponent as HitTargetComponent)?.HitTargetApi ?? new HitTargetApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs index f6c369d5e..2034b65a4 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/HitTarget/HitTargetComponent.cs @@ -110,12 +110,17 @@ public override HitTargetData CopyDataTo(HitTargetData data, string[] materialNa #region Runtime + public HitTargetApi HitTargetApi { get; private set; } + private void Awake() { - // register at player - GetComponentInParent().RegisterHitTarget(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + HitTargetApi = new HitTargetApi(gameObject, player, physicsEngine); + + player.Register(HitTargetApi, this); if (GetComponent() && GetComponentInChildren()) { - RegisterPhysics(); + RegisterPhysics(physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemComponent.cs index 205cc1538..961150f40 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/ItemComponent.cs @@ -31,9 +31,8 @@ public abstract class ItemComponent : MonoBehaviour private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); - protected void RegisterPhysics() + protected void RegisterPhysics(PhysicsEngine physicsEngine) { - var physicsEngine = GetComponentInParent(); if (physicsEngine) { physicsEngine.Register(this); } else { @@ -41,6 +40,8 @@ protected void RegisterPhysics() } } + protected void RegisterPhysics() => RegisterPhysics(GetComponentInParent()); + protected static void DrawArrow(Vector3 pos, Vector3 direction, float arrowHeadLength = 0.025f, float arrowHeadAngle = 20.0f) { Debug.DrawRay(pos, direction); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs index 458470868..9cc5f8e08 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs @@ -72,17 +72,22 @@ void IApi.OnDestroy() public void CreateBall(GameObject ballPrefab = null) { - BallManager.CreateBall(MainComponent, 25f, 1f, ItemId, ballPrefab); - } + var ballId = BallManager.CreateBall(MainComponent, 25f, 1f, ItemId, ballPrefab); + PhysicsEngine.SetBallInsideOf(ballId, ItemId); - public void CreateSizedBallWithMass(float radius, float mass) - { - BallManager.CreateBall(MainComponent, radius, mass, ItemId); + ref var ball = ref PhysicsEngine.BallState(ballId); + ref var kickerState = ref PhysicsEngine.KickerState(ItemId); + var events = PhysicsEngine.EventQueue; + ball.CollisionEvent.HitFlag = true; + + KickerCollider.Collide(ref ball, ref events, ref PhysicsEngine.InsideOfs, ref kickerState.Collision, + in kickerState.Static, in kickerState.CollisionMesh, in ball.CollisionEvent, ItemId, true); } - public void CreateSizedBall(float radius) + public void CreateSizedBallWithMass(float radius, float mass) { - BallManager.CreateBall(MainComponent, radius, 1f, ItemId); + var ballId = BallManager.CreateBall(MainComponent, radius, mass, ItemId); + PhysicsEngine.SetBallInsideOf(ballId, ItemId); } public void Kick(float angle, float speed, float inclination = 0) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs index be4eb268a..888227191 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs @@ -32,7 +32,7 @@ internal static class KickerCollider public static void Collide(ref BallState ball, ref NativeQueue.ParallelWriter events, ref InsideOfs insideOfs, ref KickerCollisionState collState, in KickerStaticState staticState, - in ColliderMeshData meshData, in CollisionEventData collEvent, in int itemId) + in ColliderMeshData meshData, in CollisionEventData collEvent, in int itemId, bool newBall) { // a previous ball already in kicker? if (collState.HasBall) { @@ -47,75 +47,75 @@ public static void Collide(ref BallState ball, ref NativeQueue.Parall // check if kicker in ball's volume set var isBallInside = insideOfs.IsInsideOf(itemId, ball.Id); - // New or (Hit && !Vol || UnHit && Vol) - if (hitBit == isBallInside) { - - if (legacyMode) { - ball.Position += PhysicsConstants.StaticTime * ball.Velocity; // move ball slightly forward - } + // if "New or (Hit && !Vol || UnHit && Vol)", continue. + if (!newBall && hitBit != isBallInside) { + return; + } + if (legacyMode) { + ball.Position += PhysicsConstants.StaticTime * ball.Velocity; // move ball slightly forward + } - // entering Kickers volume - if (!isBallInside) { - var grabHeight = (staticState.ZLow + ball.Radius) * staticState.HitAccuracy; + // entering Kickers volume + if (!isBallInside) { + var grabHeight = (staticState.ZLow + ball.Radius) * staticState.HitAccuracy; - // early out here if the ball is slow and we are near the kicker center - var hitEvent = ball.Position.z < grabHeight || legacyMode; + // early out here if the ball is slow and we are near the kicker center + var hitEvent = ball.Position.z < grabHeight || legacyMode; - if (!hitEvent) { + if (!hitEvent) { - DoChangeBallVelocity(ref ball, in hitNormal, in meshData); + DoChangeBallVelocity(ref ball, in hitNormal, in meshData); - // this is an ugly hack to prevent the ball stopping rapidly at the kicker bevel - // something with the friction calculation is wrong in the physics engine - // so we monitor the ball velocity if it drop under a length value of 0.2 - // if so we take the last "good" velocity to help the ball moving over the critical spot at the kicker bevel - // this hack seems to work only if the kicker is on the playfield, a kicker attached to a wall has still problems - // because the friction calculation for a wall is also different - if (math.lengthsq(ball.Velocity) < (float) (0.2 * 0.2)) { - ball.Velocity = ball.OldVelocity; - } + // this is an ugly hack to prevent the ball stopping rapidly at the kicker bevel + // something with the friction calculation is wrong in the physics engine + // so we monitor the ball velocity if it drop under a length value of 0.2 + // if so we take the last "good" velocity to help the ball moving over the critical spot at the kicker bevel + // this hack seems to work only if the kicker is on the playfield, a kicker attached to a wall has still problems + // because the friction calculation for a wall is also different + if (math.lengthsq(ball.Velocity) < (float) (0.2 * 0.2)) { + ball.Velocity = ball.OldVelocity; + } - ball.OldVelocity = ball.Velocity; + ball.OldVelocity = ball.Velocity; - } else { + } else { - ball.IsFrozen = !staticState.FallThrough; - if (ball.IsFrozen) { - insideOfs.SetInsideOf(itemId, ball.Id); // add kicker to ball's volume set - collState.BallId = ball.Id; - collState.LastCapturedBallId = ball.Id; - } - - // Fire the event before changing ball attributes, so scripters can get a useful ball state - events.Enqueue(new EventData(EventId.HitEventsHit, itemId, ball.Id, true)); - - if (ball.IsFrozen || staticState.FallThrough) { // script may have unfrozen the ball - - // if ball falls through hole, we fake the collision algo by changing the ball height - // in HitTestBasicRadius() the z-position of the ball is checked if it is >= to the hit cylinder - // if we don't change the height of the ball we get a lot of hit events while the ball is falling!! - - // Only mess with variables if ball was not kicked during event - ball.Velocity = float3.zero; - ball.AngularMomentum = float3.zero; - var posZ = !staticState.FallIn - ? staticState.ZLow + ball.Radius * 2 - : staticState.FallThrough - ? staticState.ZLow - ball.Radius - 5.0f - : staticState.ZLow + ball.Radius; - ball.Position = new float3(staticState.Center.x, staticState.Center.y, posZ); - - } else { - collState.BallId = 0; // make sure - } + ball.IsFrozen = !staticState.FallThrough; + if (ball.IsFrozen) { + insideOfs.SetInsideOf(itemId, ball.Id); // add kicker to ball's volume set + collState.BallId = ball.Id; + collState.LastCapturedBallId = ball.Id; } + // Fire the event before changing ball attributes, so scripters can get a useful ball state + events.Enqueue(new EventData(EventId.HitEventsHit, itemId, ball.Id, true)); - } else { // exiting kickers volume - // remove kicker to ball's volume set - insideOfs.SetOutsideOf(itemId, ball.Id); - events.Enqueue(new EventData(EventId.HitEventsUnhit, itemId, ball.Id, true)); + if (ball.IsFrozen || staticState.FallThrough) { // script may have unfrozen the ball + + // if ball falls through hole, we fake the collision algo by changing the ball height + // in HitTestBasicRadius() the z-position of the ball is checked if it is >= to the hit cylinder + // if we don't change the height of the ball we get a lot of hit events while the ball is falling!! + + // Only mess with variables if ball was not kicked during event + ball.Velocity = float3.zero; + ball.AngularMomentum = float3.zero; + var posZ = !staticState.FallIn + ? staticState.ZLow + ball.Radius * 2 + : staticState.FallThrough + ? staticState.ZLow - ball.Radius - 5.0f + : staticState.ZLow + ball.Radius; + ball.Position = new float3(staticState.Center.x, staticState.Center.y, posZ); + + } else { + collState.BallId = 0; // make sure + } } + + + } else { // exiting kickers volume + // remove kicker to ball's volume set + insideOfs.SetOutsideOf(itemId, ball.Id); + events.Enqueue(new EventData(EventId.HitEventsUnhit, itemId, ball.Id, true)); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs index 19cee1cf3..535c77a39 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerColliderComponent.cs @@ -49,7 +49,7 @@ public class KickerColliderComponent : ColliderComponent GetPhysicsMaterialData(scatterAngleDeg: Scatter); - protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new KickerApi(gameObject, player, physicsEngine); + protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) => + MainComponent.KickerApi ?? new KickerApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs index 2716db74b..8d2cd03b7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerComponent.cs @@ -146,12 +146,11 @@ public override void UpdateTransforms() private float _originalRotationZ; private float _originalKickerAngle; - private KickerApi _kickerApi; public float RotateZ { set { Orientation = _originalRotationZ + value; - _kickerApi.KickerCoil.Coil.Angle = _originalKickerAngle + value; + KickerApi.KickerCoil.Coil.Angle = _originalKickerAngle + value; } } @@ -318,22 +317,26 @@ public void OnAfterDeserialize() #region Runtime + public KickerApi KickerApi { get; private set; } + private void Awake() { _originalRotationZ = Orientation; - // register at player - GetComponentInParent().RegisterKicker(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + KickerApi = new KickerApi(gameObject, player, physicsEngine); + + player.Register(KickerApi, this); if (GetComponent()) { - RegisterPhysics(); + RegisterPhysics(physicsEngine); } } private void Start() { - _kickerApi = GetComponentInParent().TableApi.Kicker(this); - if (_kickerApi?.KickerCoil != null) { - _originalKickerAngle = _kickerApi.KickerCoil.Coil.Angle; + if (KickerApi?.KickerCoil != null) { + _originalKickerAngle = KickerApi.KickerCoil.Coil.Angle; } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightComponent.cs index c40d1c379..52d705507 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightComponent.cs @@ -200,8 +200,8 @@ private void Awake() Logger.Error($"Cannot find player for lamp {name}."); return; } + player.Register(GetApi(player), this); - player.RegisterLamp(this); var lights = GetComponentsInChildren(); _value = 0; _color = lights.FirstOrDefault()?.color ?? Color.white; diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightGroupComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightGroupComponent.cs index a64a087b1..1c8b6a1af 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightGroupComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Light/LightGroupComponent.cs @@ -71,7 +71,7 @@ private void Awake() return; } - player.RegisterLampGroup(this); + player.Register(GetApi(player), this); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/ScoreMotorComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/ScoreMotorComponent.cs index b83956f96..9cf911f60 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/ScoreMotorComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/ScoreMotorComponent.cs @@ -95,9 +95,15 @@ public class ScoreMotorComponent : MonoBehaviour, ISwitchDeviceComponent #region Runtime + public ScoreMotorApi ScoreMotorApi { get; private set; } + private void Awake() { - GetComponentInParent().RegisterScoreMotorComponent(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + ScoreMotorApi = new ScoreMotorApi(gameObject, player, physicsEngine); + + player.Register(ScoreMotorApi, this); } private void Switch(string id, bool isClosed) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/StepRotatorMechComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/StepRotatorMechComponent.cs index cb392f9d0..faab18409 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/StepRotatorMechComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Mech/StepRotatorMechComponent.cs @@ -70,6 +70,8 @@ public class StepRotatorMechComponent : MonoBehaviour, ISwitchDeviceComponent, I public event EventHandler OnMechUpdate; + public StepRotatorMechApi StepRotatorMechApi { get; private set; } + private void Awake() { var player = GetComponentInParent(); @@ -78,7 +80,10 @@ private void Awake() return; } - player.RegisterStepRotator(this); + var physicsEngine = GetComponentInParent(); + StepRotatorMechApi = new StepRotatorMechApi(gameObject, player, physicsEngine); + + player.Register(StepRotatorMechApi, this); } public void UpdateRotation(float speed, float position) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs index 61731e108..9dc0e0b4c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideColliderComponent.cs @@ -55,6 +55,6 @@ public class MetalWireGuideColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new MetalWireGuideApi(gameObject, player, physicsEngine); + => MainComponent.MetalWireGuideApi ?? new MetalWireGuideApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs index 27547784e..769b365bb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/MetalWireGuide/MetalWireGuideComponent.cs @@ -90,11 +90,16 @@ public class MetalWireGuideComponent : MainRenderableComponent().RegisterMetalWireGuide(this); - RegisterPhysics(); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + MetalWireGuideApi = new MetalWireGuideApi(gameObject, player, physicsEngine); + + player.Register(MetalWireGuideApi, this); + RegisterPhysics(physicsEngine); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs index 4ebc4d8b3..5176c90ba 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldColliderComponent.cs @@ -55,6 +55,6 @@ public class PlayfieldColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new PlayfieldApi(gameObject, player, physicsEngine); + => MainComponent.PlayfieldApi ?? new PlayfieldApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs index 1035f641b..7c1085bca 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Playfield/PlayfieldComponent.cs @@ -99,14 +99,14 @@ public float3 PlayfieldGravity(float strength) { return new float3(0, math.sin(math.radians(slope)) * strength, -math.cos(math.radians(slope)) * strength); } + public PlayfieldApi PlayfieldApi { get; private set; } + private void Awake() { - GetComponentInParent().RegisterPlayfield(gameObject); - var meshComp = GetComponentInChildren(); - if (meshComp) { - // todo re-enable system - // World.DefaultGameObjectInjectionWorld.GetOrCreateSystemManaged().CollideAgainstPlayfieldPlane = meshComp.AutoGenerate; - } + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + PlayfieldApi = new PlayfieldApi(gameObject, player, physicsEngine); + player.Register(PlayfieldApi); transform.RotateAround(Vector3.zero, Vector3.right, -RenderSlope); } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs index 553049073..cdb441d81 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerColliderComponent.cs @@ -56,6 +56,6 @@ public class PlungerColliderComponent : ColliderComponent GetPhysicsMaterialData(); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new PlungerApi(gameObject, player, physicsEngine); + => MainComponent.PlungerApi ?? new PlungerApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs index 2296624ab..b7d9867b3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Plunger/PlungerComponent.cs @@ -74,12 +74,17 @@ public class PlungerComponent : MainRenderableComponent, #region Runtime + public PlungerApi PlungerApi { get; private set; } + private void Awake() { - // register at player - GetComponentInParent().RegisterPlunger(this, analogPlungerAction); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + PlungerApi = new PlungerApi(gameObject, player, physicsEngine); + + player.Register(PlungerApi, this, analogPlungerAction); if (GetComponent()) { - RegisterPhysics(); + RegisterPhysics(physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs index 6a6ca03a2..d24b10d64 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveColliderComponent.cs @@ -61,6 +61,6 @@ public class PrimitiveColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new PrimitiveApi(gameObject, player, physicsEngine); + =>MainComponent.PrimitiveApi ?? new PrimitiveApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs index 80248f59f..90a555e0f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Primitive/PrimitiveComponent.cs @@ -243,11 +243,18 @@ public override void CopyFromObject(GameObject go) #region Runtime + public PrimitiveApi PrimitiveApi { get; private set; } + private void Awake() { _originalRotateZ = ObjectRotation.z; - GetComponentInParent().RegisterPrimitive(this); - RegisterPhysics(); + + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + PrimitiveApi = new PrimitiveApi(gameObject, player, physicsEngine); + + player.Register(PrimitiveApi, this); + RegisterPhysics(physicsEngine); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs index a7ce42205..abf566dc1 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampColliderComponent.cs @@ -60,6 +60,6 @@ public class RampColliderComponent : ColliderComponent public override PhysicsMaterialData PhysicsMaterialData => GetPhysicsMaterialData(Elasticity, friction: Friction, scatterAngleDeg: Scatter, overwrite: OverwritePhysics); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new RampApi(gameObject, player, physicsEngine); + => MainComponent.RampApi ?? new RampApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs index 687980198..4cc1f25c7 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ramp/RampComponent.cs @@ -123,11 +123,16 @@ public class RampComponent : MainRenderableComponent, #region Runtime + public RampApi RampApi { get; private set; } + private void Awake() { - // register at player - GetComponentInParent().RegisterRamp(this); - RegisterPhysics(); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + RampApi = new RampApi(gameObject, player, physicsEngine); + + player.Register(RampApi, this); + RegisterPhysics(physicsEngine); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs index 4ae3a9362..bcd44bc7f 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberColliderComponent.cs @@ -55,6 +55,6 @@ public class RubberColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new RubberApi(gameObject, player, physicsEngine); + => MainComponent.RubberApi ?? new RubberApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs index bb718e0a2..ecc4f402e 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Rubber/RubberComponent.cs @@ -86,11 +86,16 @@ public class RubberComponent : MainRenderableComponent, #region Runtime + public RubberApi RubberApi { get; private set; } + private void Awake() { - // register at player - GetComponentInParent().RegisterRubber(this); - RegisterPhysics(); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + RubberApi = new RubberApi(gameObject, player, physicsEngine); + + player.Register(RubberApi, this); + RegisterPhysics(physicsEngine); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs index 4ee2a06da..bd90929bb 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerColliderComponent.cs @@ -34,6 +34,6 @@ public class SpinnerColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new SpinnerApi(gameObject, player, physicsEngine); + => MainComponent.SpinnerApi ?? new SpinnerApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs index 93092b28c..d7fe56f65 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Spinner/SpinnerComponent.cs @@ -92,11 +92,16 @@ public class SpinnerComponent : MainRenderableComponent, #region Runtime + public SpinnerApi SpinnerApi { get; private set; } + private void Awake() { - // register at player - GetComponentInParent().RegisterSpinner(this); - RegisterPhysics(); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + SpinnerApi = new SpinnerApi(gameObject, player, physicsEngine); + + player.Register(SpinnerApi, this); + RegisterPhysics(physicsEngine); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotComponent.cs index 459aa4f92..10ea2821d 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SlingshotComponent.cs @@ -91,12 +91,17 @@ public class SlingshotComponent : MonoBehaviour, IMeshComponent, IMainRenderable IEnumerable IDeviceComponent.AvailableDeviceItems => AvailableSwitches; - #region Runtime + public SlingshotApi SlingshotApi { get; private set; } + private void Awake() { - GetComponentInParent().RegisterSlingshotComponent(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + SlingshotApi = new SlingshotApi(gameObject, player, physicsEngine); + + player.Register(SlingshotApi, this); } private void Start() diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs index 369a74778..26f38178c 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceColliderComponent.cs @@ -67,6 +67,6 @@ public class SurfaceColliderComponent : ColliderComponent GetPhysicsMaterialData(Elasticity, ElasticityFalloff, Friction, Scatter, OverwritePhysics); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new SurfaceApi(gameObject, player, physicsEngine); + => MainComponent.SurfaceApi ?? new SurfaceApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs index a15ce6d09..ee7dde8f3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Surface/SurfaceComponent.cs @@ -66,12 +66,17 @@ public class SurfaceComponent : MainRenderableComponent, ISurfaceCo #region Runtime + public SurfaceApi SurfaceApi { get; private set; } + private void Awake() { - // register at player - GetComponentInParent().RegisterSurface(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + SurfaceApi = new SurfaceApi(gameObject, player, physicsEngine); + + player.Register(SurfaceApi, this); if (GetComponentInChildren()) { - RegisterPhysics(); + RegisterPhysics(physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterComponent.cs index 8427c0828..8e83e1883 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Teleporter/TeleporterComponent.cs @@ -71,6 +71,8 @@ public class TeleporterComponent : MonoBehaviour, ICoilDeviceComponent #region Runtime + public TeleporterApi TeleporterApi { get; private set; } + private void Awake() { var player = GetComponentInParent(); @@ -84,7 +86,10 @@ private void Awake() ToKicker.GetComponent().enabled = false; } - player.RegisterTeleporter(this); + var physicsEngine = GetComponentInParent(); + TeleporterApi = new TeleporterApi(gameObject, player, physicsEngine); + + player.Register(TeleporterApi, this); } #endregion diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs index 58b749c3e..1d78689b8 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerColliderComponent.cs @@ -52,6 +52,6 @@ public class TriggerColliderComponent : ColliderComponent GetPhysicsMaterialData(); protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine) - => new TriggerApi(gameObject, player, physicsEngine); + => MainComponent.TriggerApi ?? new TriggerApi(gameObject, player, physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs index afef30824..315d34357 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trigger/TriggerComponent.cs @@ -82,13 +82,17 @@ public class TriggerComponent : MainRenderableComponent, #region Runtime + public TriggerApi TriggerApi { get; set; } + private void Awake() { - // register at player - GetComponentInParent().RegisterTrigger(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + TriggerApi = new TriggerApi(gameObject, player, physicsEngine); + player.Register(TriggerApi, this); if (GetComponentInChildren()) { - RegisterPhysics(); + RegisterPhysics(physicsEngine); } } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughComponent.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughComponent.cs index dc78680bd..8dff2ae11 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughComponent.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Trough/TroughComponent.cs @@ -303,9 +303,14 @@ public IEnumerable AvailableCoils { #region Runtime + public TroughApi TroughApi { get; private set; } + private void Awake() { - GetComponentInParent().RegisterTrough(this); + var player = GetComponentInParent(); + var physicsEngine = GetComponentInParent(); + TroughApi = new TroughApi(gameObject, player, physicsEngine); + player.Register(TroughApi, this); } #endregion From 1c339a3a499ebab47915e7956135d7cbde1464cb Mon Sep 17 00:00:00 2001 From: freezy Date: Mon, 30 Oct 2023 00:19:38 +0100 Subject: [PATCH 159/159] kicker: Properly handle new ball. --- .../VisualPinball.Unity/Game/Player.cs | 1 - .../VPT/Ball/BallManager.cs | 22 +++---------------- .../VPT/Kicker/KickerApi.cs | 10 ++++----- .../VPT/Kicker/KickerCollider.cs | 8 ++++--- 4 files changed, 12 insertions(+), 29 deletions(-) diff --git a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs index e57523cf8..d197481f3 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs @@ -139,7 +139,6 @@ public Player() private void Awake() { - DebugLogger.ClearLog(); _tableComponent = GetComponent(); var engineComponent = GetComponent(); diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs index 8c10682ee..9d25dd573 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Ball/BallManager.cs @@ -40,44 +40,28 @@ public BallManager(PhysicsEngine physicsEngine, Player player, Transform parent) _parent = parent; } - public int CreateBall(IBallCreationPosition ballCreator, float radius = 25f, float mass = 1f) - { - return CreateBall(ballCreator, radius, mass, 0); - } - - public int CreateBall(IBallCreationPosition ballCreator, float radius, float mass, int kickerId, GameObject ballPrefab = null) + public int CreateBall(IBallCreationPosition ballCreator, float radius = 25f, float mass = 1f, GameObject ballPrefab = null) { var localPos = ballCreator.GetBallCreationPosition().ToUnityFloat3(); localPos.z += radius; - var ballId = NumBallsCreated++; if (!ballPrefab) { ballPrefab = RenderPipeline.Current.BallConverter.CreateDefaultBall(); } var ballGo = Object.Instantiate(ballPrefab, _parent); var ballComp = ballGo.GetComponent(); - ballGo.name = $"Ball {ballId}"; + ballGo.name = $"Ball {NumBallsCreated++}"; ballGo.transform.localScale = Physics.ScaleToWorld(new Vector3(radius, radius, radius) * 2f); ballGo.transform.localPosition = localPos.TranslateToWorld(); ballComp.Radius = radius; ballComp.Mass = mass; ballComp.Velocity = ballCreator.GetBallCreationVelocity().ToUnityFloat3(); - ballComp.IsFrozen = kickerId != 0; + ballComp.IsFrozen = false; // register ball _physicsEngine.Register(ballComp); _player.BallCreated(ballGo.GetInstanceID(), ballGo); - // handle inside-kicker creation - if (kickerId != 0) { - ref var kickerData = ref _physicsEngine.KickerState(kickerId); - if (!kickerData.Static.FallThrough) { - _physicsEngine.SetBallInsideOf(ballComp.Id, kickerId); - kickerData.Collision.BallId = ballComp.Id; - kickerData.Collision.LastCapturedBallId = ballComp.Id; - } - } - return ballComp.Id; } diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs index 9cc5f8e08..94b41e856 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerApi.cs @@ -70,15 +70,14 @@ void IApi.OnDestroy() { } - public void CreateBall(GameObject ballPrefab = null) + public void CreateBall(GameObject ballPrefab = null, float radius = 25f, float mass = 1f) { - var ballId = BallManager.CreateBall(MainComponent, 25f, 1f, ItemId, ballPrefab); - PhysicsEngine.SetBallInsideOf(ballId, ItemId); + var ballId = BallManager.CreateBall(MainComponent, radius, mass, ballPrefab); ref var ball = ref PhysicsEngine.BallState(ballId); ref var kickerState = ref PhysicsEngine.KickerState(ItemId); var events = PhysicsEngine.EventQueue; - ball.CollisionEvent.HitFlag = true; + ball.CollisionEvent.HitFlag = true; // HACK: avoid capture leaving kicker KickerCollider.Collide(ref ball, ref events, ref PhysicsEngine.InsideOfs, ref kickerState.Collision, in kickerState.Static, in kickerState.CollisionMesh, in ball.CollisionEvent, ItemId, true); @@ -86,8 +85,7 @@ public void CreateBall(GameObject ballPrefab = null) public void CreateSizedBallWithMass(float radius, float mass) { - var ballId = BallManager.CreateBall(MainComponent, radius, mass, ItemId); - PhysicsEngine.SetBallInsideOf(ballId, ItemId); + BallManager.CreateBall(MainComponent, radius, mass); } public void Kick(float angle, float speed, float inclination = 0) diff --git a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs index 888227191..e9cc0b8ec 100644 --- a/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs +++ b/VisualPinball.Unity/VisualPinball.Unity/VPT/Kicker/KickerCollider.cs @@ -51,7 +51,7 @@ public static void Collide(ref BallState ball, ref NativeQueue.Parall if (!newBall && hitBit != isBallInside) { return; } - if (legacyMode) { + if (legacyMode || newBall) { ball.Position += PhysicsConstants.StaticTime * ball.Velocity; // move ball slightly forward } @@ -60,7 +60,7 @@ public static void Collide(ref BallState ball, ref NativeQueue.Parall var grabHeight = (staticState.ZLow + ball.Radius) * staticState.HitAccuracy; // early out here if the ball is slow and we are near the kicker center - var hitEvent = ball.Position.z < grabHeight || legacyMode; + var hitEvent = ball.Position.z < grabHeight || legacyMode || newBall; if (!hitEvent) { @@ -88,7 +88,9 @@ public static void Collide(ref BallState ball, ref NativeQueue.Parall } // Fire the event before changing ball attributes, so scripters can get a useful ball state - events.Enqueue(new EventData(EventId.HitEventsHit, itemId, ball.Id, true)); + if (!newBall) { + events.Enqueue(new EventData(EventId.HitEventsHit, itemId, ball.Id, true)); + } if (ball.IsFrozen || staticState.FallThrough) { // script may have unfrozen the ball

- -*This section will contain the scripting API documentation.* - - diff --git a/VisualPinball.Unity/Documentation~/apple-touch-icon.png b/VisualPinball.Unity/Documentation~/apple-touch-icon.png deleted file mode 100644 index ecaa8ddfc5edecf81b5f79a349548d03637b820b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6599 zcmaKRRZtvEu2<-C0;XxP&A?kl^gXq5*=t%i6)pD*42R$;e+r2005D?8btp|H~p{RVm)C-|9IPz z!g{Z$tq1_rClWkbJ$tg5tkv|j0RTS^03av~0Qmjn3OWD)JOu!NpOyfCR3-pG1^PYnruhbS}z~;z|1-(wug!Iq#^n(fB(r;OozwT-y=?b}G*i_7! zw3B~n=CCm0Q{cw1g~v9tsHo(yj;3*)er}Cg^46G9J?Vf%&nRh7s6=o5-MjAVv^_+L zqXhfHAzb^HL3)E9F4Kct$wummUITPVXw1KvrT8U-EZ_5OcYlVBre4ifXlx*f* z6ub7Nr!0QtFAYN1D3}&mB}wL9pb9x{LfHnFpwNyz?UeM6ae>I*4aNM63A|Dz&Qu@S z6gm1g{KW=zd0H0;V;21_|ABjnDZQO4vQ4hv0h`=W`Yq@3`aI4Abo;z#Uo&rg=QKhG z@>W3P!}V{~jUzV^d@p$Nf|>nT0;oDntJUwS)dS0bk6|p`MRGo5|N7H#8=J3LetqGQ zotQh=Xt_2m@e3+w%uJHuC3`c0DBrV|GiDU&d6ECpN_bG}m;3aZuZW&Y>7ooZ=%6Hs z|7J#jD0c$k)Ihmkj*q(0T7^SLYBFcVJ639?8^W2P)OfOnOZJ8&gKH<^K37%#2Jyb# z)-0UY5c`_QfFvMPiC+}jx=gjp9Y15{CNmO|=GbUWphS*?uI{tU6H(pcVnN?bLNVxn zF6tRiArF7q66xqwwf12J6XPE&Gh75(%y53K>zAVMR8Xc!TrU7cRBYvb{Wxbv7Qhs% zgpiGEhzi&g#>6$3NIDd=d-kh=|9o`D^VpiSc)2+3TvFzQ?TRpu|4ty@sk-pL=^B)T ztFB^V$wxcgz109AzpV17X{FUGe${knnnD#wiA{yri4M6I9^)?;BZm|JN(8&wUD0`m zPdE_j52mi{-?8L@_uF@k()OjkkM+>3cexJe0HspzoVxe!0;$R^d)PiTPE%SdHO z&Tffb>*Cyf7mgeY&4VrYsTY?wE$HF7f2q8-WDJ6%dHXJ5r8aKA?6D{Lp!hMEHrPP} z_x+v8lD7o%YBR!^k_MT0p0uEzr%64;>;Do>WPN*8BKn)<+S1NVIAq!2Ibk+~HL9Y`_R#VM0oBGlYvyj*9 zuO^pm6Dp@2uJuMm2i;#@RN|1WKI~j4In#BG3n#ez{1kUI=Y3*LeBuiBV`?WQa&*wo z`2wG0Z*riUzRxasP-ENq!5zhPD#0@CCQl*|YEHM@6k$9qK+Uxd;bQ>joCb*Wc;X)# z@>0V+VF97uTGln5h?al%togI#?emPAEzi|!uQJEQ>6bkcMieY-D-fLFF-cIB?gzg3 zP6Bh&0r{NaOE^+BaIdi0UdviK(#0`jqtIV+w~oQ~u<&Rb9G15V=xv9RpIH zf%DVHsX}OHN5nY}R>rhkJ-}bh;IE$5rQ5Ex6P;^`05USiJg;;M(J%Q-=m-Kb=Jj?5 zp|m%Zx8g3;B}idP>4pK3d<1w_rES&0^9}w^%5AnRc^6rsx?{ioBbO81XuP!)NzRN6 zs{qV}4GIUrf{c(3Y2&Q^&ZnfTg~`fZWky82U85daWHqef+yWnOLIg%Mbfl3Vq7Iq) zSQi3bmt^Nu*v&@dq@incIpVgh8Q@^g5KzZ-WnRbv=s6Hw1@NlxH>BU##`NSTuATR# z`^G{F;-jf^aIXDHSb!(0?J_5TmF7Cg;NWD*r z9*K;MT$5dF)e2_`3mJ#lWsRMX*72rHSEj4fN6ZgE5afjgNS3O@+DK5wA-b{C#<5WE zg4DP~klM5?S($Q}B5;Txp~R1Sw{q4&luadf&N^j3lf4~}XvB<`V~o1xw(dv$ijUk@ z)xiis;#5yX8mZF{bz>|MdOV`YTjAJ?gp#>>gF|O5#W{Wcuv48Uu;40E_}<-G_w<` zGSkBa(wz(9MC?;saqm>kvwZNem24&b;)HeQ*@5L$#ctTDgV8wl>*|Z-=aG;vO4wPk z!(aJ>#vK!+kvZQZ<5~_F=F6|`9yM_1xrO5AT^3^o`j&qrEUp-*_cFQQzy+t^*@0thM$n5AF!JYr}rZL@xIdAm{^o8MatM_QHSe0P$ea`(vfd%eK@Pa37;K>scK)#t`&kbrDfdqVo0?q1XL zt^w0tPj&j02(!(1m;q_GnATlw-d}_&^w4$rt73V`DCqdNtGl5e4zsH4eRB>Y?A%Ff zKD(04(Udkh6glfElM>LpVm!lbm+oS49mc}eyZH#>$}}Sp!7nIcvm*v?_^WtbEBGrs z7JX+kyBDlvOn!WXjZF4ugcB`uZDGIGMhQ7Gu{nypzaVm--BoO-tu~PZhkIK(;?4MV zs*JObd*vfdd(PKT&xv{j_XMlG7*}gKCaHYawqk$5d(gE3Y%_Ov>e!RM!%qyM+$Pn` zdwr;vh(8uekT1`y+A>jeAwB}ZIveDt&1z$~yb`p#e-(KSo3hqczvCZ6Syx8Op2}!D zHZgnuAH?fqlJ3qZ6#%lU~gW$3t=) z!u;oNAil!OXLu-g_$$wb+(6BsuxlanBaIng0TcSjhum0i?4{xA9hdfFdf$G^AWjoZ zgC;F(wv&z-Pe*)rMRzMX`~tNjO7&taLArJQM|*upAJXc1xn25XHnme_6kcLa=x${VmlE6G-oGj;&pqF4=nDLYR%fI2L*aP z`@E5yo{;Exi(vM0b6ZBV6cv$t&hhdUwnRK-&YO<-rAaI)wJX`$O^gf6DEFlrkq4qO zqb)T|^il5w%dc01zvKA_E{0J%#IdRYsUwz2i~!ad*qjidV`plLa}*zQ*P!9@Tgpv0 z?eEj6Ea;HjWR~CBgZ9_@R@$$udObME)6f!(PDuROAOWDBQ4L5wzQ7{5JEa#ksC3WiMQJx6ffokZP-p zfRJxUo|K(zH62ExN#)?zdeVu^j;$L{z2%H&B&`r0{8QnqJByw&&)6r1k^LmS@1PJR z(n~Vq6&|v~{zi)oO)Fr$RPp8KHrq`?o0EU%6a8E_*^Xcx9_qTVj+JpRRM^@7+~5cN zsWZnB4X5n0XoaCc&n)nstKKWCM7WaA=k2& zkaMCqE8~te#0SeFLn~>%@1JkTfOdrMINb3N48q$9#^TZMv zuZ;1@THGw*3I^h{bEt1l^S7M!$Q_~x>~RCNf+f-wm|*aCgHDWca*G06>Y1#O>(Af# z5slzFg=s@`#_-{Bg^U^Tbu3-Zn@!<}vWFm2BC;1P=Yk}v0-@Qf728>d=x|!vpNmvX zy@npLo=IB1I_;37AtL;zd*S02>r6Y_Wk6aY^}ancP_A^BdTq`*z9Cjf73>LD#BWW` zbQJd^$) z7HT|yOo8dN_yxH$M~fcJdOrA@xXio?Jjld(WUzzh20ma40|NVRW#+(>BPf z|2b(S4uM5Idxbw`%%OKA085B0%#kTge$PPm&^Anvz-w?;7N7bnqWDVS+YUqG&6h%o zRgYSrxeMzfXZ&ZTPkNV;@V-ei7TOx2raoJ}D=a&>n|&ocf8GRC=4btBW16}DuAtwj zxPA(LwtAgFw7`QRbProYoGMMVr=EI0H#0~9`?K283`e~F z8QIdqbK%xmiWsKO@1qP($7Lc(DWY>pVLfMJF)~8IKnN;!}+BBR`lgQR_l;;Ld3(x zijJ_dJuaxxXT8`{x%_kJa#s1{s;iX8hYkB&?wDoBoonFOS3`8}*4WM4umYjMgaL!TurlQe=D)FyB8bw<4-D6@&EFgHc4dMp;VJ9SrhwU})EkU<);uOxrIz1|3L{?L zDa79|jJ~pyqG(IcYJ%mPXVL)2U(Ze7nOdEfW{fTy7zZ0iGLc1lZ+0mIH_ks+UwGCE z_Xz?xmw_eB*jXwv^i&Wi5o+Jsmv?{wiJLs=Lw9 zETygnL`zQ=_L`z?-pY4d;QiGQ4Qto+Q50Q_Zn2v!mAVSiw7m zv%Bpv{l*bKKlni>zWO8$Nu(3eM`VyCHqfaQe<=zukmQq|(qtpfC8kn>-CeF2^V+#t zT_uJSZ1vhwD0kDLy8^WP-(`@dUyA*C_O@k^#>ms_C)DYV2zZ#XKSP^t=-B=hQ_yAH z(o}B5cii>?QySq_Cpz;DI{yaipeUT#so}1QLc?1_JA?9bBY%GI1;wQ}k0j{h#QMNO z^`Eu) zJuxkNIWx8$E|!?Q8t0e;Jt6SLY5GK8{h_MF_A?FZC8RrR&dGA3>LdL{Ou@wT=i|)f zytSWR+w*45U@l>UI=P6>ggmf8GhLMA>?1#AahXZJFcX?-pDQKM6S*+zo;a!!_JS@- z&`VkJXBii{S^BijHG@KBXpV3gRnV#Nty5IYwxKGja;N4B;E>{Yk#@n+HWUN_cA-i& zOYEX9%NL2hQ0;s({SnJ|`qUY_$REpS5Z2^KkIfI4M+mTIQi`<7wB?xljPHK@ zi&+vUkc?OQZCUB#-nyv}00-BiN9kJ2xhv0DRw}9t@HbbZyQH@5H_tb3!jo{)abJ9n zsdBtMi-DORblc>_smZeA(^A5OMd@X&?sxh3m&>p}A*!70{>y?w4!MJ^Q-SU1i%-|v z#i$92v844ls`hm{;i7fct(}eLm3~*kVY`jEAO3(i#GUC1d&-3AxsR@thu{ zxQ$yxp-D%my?4K5q>OFi4gzqexOlY;E!pZdm|`seqNTDmO6!_@@zew#ghRA6nv%mB zl#RZtR%lIX`NzfR+T~29N@u19uhMD_F`*wYYQq2PPboSFm*5@C$$fWUQqozNwEk8Y zj##>P87hZ(7e3fp2?Q&c*5;1H zApg+V4g-zzDF?H*vR4$C_WYr2ZCr?*GX(IuBn9^g}^Vd6~W=1mc(N?=h`aQzr( z$if?iU6{x6dzSeEWHEJ80Tb86d>B$Xp!q}LyI3zRJ49AQ0-ULvl43h`H=CjBY+P%e z#;;2O4H5f}gNil<+~3&YnC#+6Ct4vpoHg-a*(thU{ir=n)Sh4SWUdMXSQk$Q(SGgD zlN84(rOLJYdGnmoPH~nsOWXAwR-3TP3a2rw%w(p*&_R3LTp`Gzh zT#6Q5cPyaK%tjE#WJJ^*i57Y{(TXv^y;iRnn*Jh}*U@f+r`JrH(Q+7dYuyibRwI*W z?#5$>XH2^dZyOBr8<9^`7djtWnLDJ?kKfCuBfA8!B-Qn@DUpNWaRZ(bn>^l%oaDYh zZEc&65qxxw{1S8barm#Ng5Q(T;6ZLyf zxDD|oo5IGoX-t|oE-Aa0xi=8t084?gWrnTd#`CMM=+^ukW1AX3DhNp`y5p-%R%v&Y z!&NA@{pht*`#VClYX_0f{hj2Y>J8$0LX`FlYcqDx$LBaLx6Oubg%EbQ% zWbQulZULZ|pti@SUk7%CiYdaz3Slc{?QZ*|073#n0(=6Jd_t0jf&x-P!cqcayaGZ} z0s=BGJ_!F`0WNMf4tBo(?*MJJzQm^h6F);!guazG6U^Ps&cWH13E>N~WpaQatN{R@ z-0e$3T(~h8*T~CJl=`kd0LV(fZ%shXO0Jno0VHRF1c~(709hLinMN08hWb(cbp1G^ eL288>{D7ZSq=-u;(e$Sh0Cg1|NUf4($o~K$W@YRE diff --git a/VisualPinball.Unity/Documentation~/docfx.json b/VisualPinball.Unity/Documentation~/docfx.json index c6e7308c0..c64cd67b1 100644 --- a/VisualPinball.Unity/Documentation~/docfx.json +++ b/VisualPinball.Unity/Documentation~/docfx.json @@ -1,103 +1,63 @@ { - "metadata": [ - { - "src": [ - { - "files": [ - "VisualPinball.Unity/**.csproj", - "VisualPinball.Unity.Patcher/**.csproj" - ], - "src": "../" - } - ], - "dest": "api", - "disableGitFeatures": false, - "disableDefaultFilter": false, - "filter": "filterConfig.yml" - } - ], - "build": { - "content": [ - { - "files": [ - "api/**.yml", - "api/index.md" - ] - }, - { - "files": [ - "creators-guide/**/toc.yml", - "creators-guide/**.md", - "plugins/**/toc.yml", - "plugins/**.md", - "toc.yml", - "*.md" - ] - }, - { - "files": "CHANGELOG.md", - "src": "../.." - } - ], - "resource": [ - { - "files": [ - "**/*.png", - "**/*.gif", - "**/*.jpg", - "**/*.svg", - "**/*.ico", - "**/*.webp", - "**/*.webmanifest", - "../VisualPinball.Unity.Editor/Resources/Icons/*.png", - "CNAME" - ] - }, - { - "files": "static/**/*.woff*", - "dest": "/fonts" - }, - { - "files": "static/*.css", - "dest": "/styles" - } - ], - "overwrite": [ - { - "files": [ - "apidoc/**.md" - ], - "exclude": [ - "obj/**", - "_site/**" - ] - } - ], - "dest": "_site", - "globalMetadataFiles": [], - "fileMetadataFiles": [], - "template": [ - "default", - "template/vpe", - "template/lightbox-featherlight" - ], - "postProcessors": [ "ExtractSearchIndex" ], - "globalMetadata": { - "_appTitle": "VPE Documentation", - "_appFooter": "Copyright © 2022 VPE Team", - "_gitContribute": { - "branch": "master" - } - }, - "sitemap":{ - "baseUrl": "https://docs.visualpinball.org/", - "priority": 0.5, - "changefreq": "weekly" - }, - "markdownEngineName": "markdig", - "noLangKeyword": false, - "keepFileLink": false, - "cleanupCacheHistory": false, - "disableGitFeatures": false - } -} \ No newline at end of file + "build": { + "content": [ + { + "files": [ + "creators-guide/**/toc.yml", + "creators-guide/**.md", + "plugins/**/toc.yml", + "plugins/**.md", + "toc.yml", + "*.md" + ] + }, + { + "files": "CHANGELOG.md", + "src": "../.." + } + ], + "resource": [ + { + "files": [ + "**/*.png", + "**/*.gif", + "**/*.jpg", + "**/*.svg", + "**/*.ico", + "**/*.webp", + "**/*.webmanifest", + "../VisualPinball.Unity.Editor/Resources/Icons/*.png", + "CNAME" + ] + } + ], + "output": "_site", + "globalMetadataFiles": [], + "fileMetadataFiles": [], + "template": [ + "default", + "modern", + "template/vpe" + ], + "postProcessors": [ "ExtractSearchIndex" ], + "globalMetadata": { + "_appTitle": "VPE Documentation", + "_appFooter": "Copyright © 2023 VPE Team", + "_appFaviconPath": "favicon.png", + "_gitContribute": { + "branch": "master" + } + + }, + "sitemap":{ + "baseUrl": "https://docs.visualpinball.org/", + "priority": 0.5, + "changefreq": "weekly" + }, + "markdownEngineName": "markdig", + "noLangKeyword": false, + "keepFileLink": false, + "cleanupCacheHistory": false, + "disableGitFeatures": false + } +} diff --git a/VisualPinball.Unity/Documentation~/favicon-16x16.png b/VisualPinball.Unity/Documentation~/favicon-16x16.png deleted file mode 100644 index 4b05796cc03f976bc6960ada5f7b1bc6200f64fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 728 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^xl_H+M9WCijSl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|U1(2s1Lwnj--eWH0gbb!C6TDa$3!#xJ_7h=GAI!_&nvMB{wx#IxEij3P(t z^Y2OTHIa1sIishiW?H|<&6z=`dg>FCk~OWRC+>eB%B`*X^M>Zpb54_j4xe%|{BlC% zo-FIa;xxM?rBc&Hz>T4|@9&p-!y_xCH z5=)t{#QC{Z(i54_g}B_Tm{~JlG}{M+wKQB z+sr6iv2{D=Y)`8dN*$gO-B-`fcHO_&Y>~C5v2^FJ^B)Qh7^<1_Y^W)>imlXVaOQZp zGuLvuXXJz)m8Vf*OY;3*{QFlr;oGl>KW^7l^eiK%Yf5%(zf#V$fQjWo{ABrG89u8I zFPi4^EhWsps8Z|4Rqq4ln~JqE4O5(|%A{)6{_K99z2nDQ?_}+zhJKl^E^2Iiy8XFq zM%MjD>)v>M7s~n^ztJS{ve~o_l~uQ!TvtRzXjg2Gn{r&Z{Ji(B327VM1Zo;`#S-Up zKbiJ0tj#S37!9f=t`Q|Ei6yC4$wjF^iowXh$UxV?QrE~b#L&RX$k@ujOxwW7%D})z zwAvU&LvDUbW?Cg~4Za?S`+*w5t3o15f)dLW3X1a6GILTDN-7Id6*3D-k{K8(<~;ty z!%-Nfp>fLp^cl~mK@7~w+k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SSr1Gg{;GcwGYBLNg-FY)wsWq-mc%O%cUA=LGRfq^;R)5S5wE*ixs6S1jNj9R6ic<$g`NB^C{_3H@{tmQdSa^{xNpnBOYQk5jngP zzEjw5GC1Cia8k+AVA|!I8&kS^&FgU`_{e3hwnsqYd@I%e0ufy_w(j_{#kqe znVEc@&oevBpBXnCezq=tR@vrXW>)+|PPwudeMdV}cs+*p&k$pm48SH15Fj%o{SR8AZeLPwwVuQgEmfbt2?^>FA zwCmvVD<7Fe=Nv!$r~MW4M0qiW57w_;dY5cJzIuDmNiV;J8(CRfI0V$rupHlU#M{F2 zgWTc6x3rCF1sRe9Q?9KqjkPNXyX|PKx9@?VROctN<`*1Jv)=A#u+y8d>hzb@^|vmI z-;rO_?r_Ys(4RZ>Ni|5rtJ3^_A2MfdMYcKs># zPU+zE7hfJc2$j0o(99d6B=hi$>DOH`B5K@>i*F>TJeR3X5H`K?(f03?ikV*>CIzN- zd{T~^G=FvZNj{y}m8uL8hMTi=E}HGW#~v3~6-~>Xd4ZLFbDE`J zn~R0K_&I-TO0t&u&m&TQ9Zv;1OyQ`X_(Z~1^4^5H8Ru39v`WniSZ(B<+g~2U?{cGE zzSXU#Wc@8=!~grW8@A5aob~Kg@Ty0NCd)b=9XMw&aYvPJn?lj&`dZ=Hr{8_wadi8Y z|E!r4+4>is2~>&RZD`_ec6g!32jw7!B_E7rL)uj)?=(HIeufMChdGn&7^*DQPbKql zD4S2;pW!!W8r%KLMyiuH1;45->)z|KEY4;RoAJV+$!p7{?2Bu{-afbP5IY;9dcb7C zyA!oRJH0!;uSnk+=Cv=5E1)%nWBKjpm$KHgD3tAPkXRj%oRlb_ZxmG&r5eq!;b2sP zQbqRU|M}m{rI?%S<=F+|fVoe##5JNMC9x#cD!C{XNHG{07#ZjqSn3*Ch8P-H85vs{ zm}?stSs572N-Aha(U6;;l9^VCTf=Mn6V^Zt;Z-3KB|(Yh3I#>^X_+~x3MG{VsS23| zCCLm76>}bc;^8O^)6h8OfBKB)(;xZee9%@5v&}!U`@8CWlj)l{bedoW618 m#E~;cWR9?(Ztz&(rN{6}T(IPmlj&5T6%3xPelF{r5}E)@ss%m( diff --git a/VisualPinball.Unity/Documentation~/favicon.ico b/VisualPinball.Unity/Documentation~/favicon.ico deleted file mode 100644 index 5bea928f4c902b49b17126aaaee0a2139766d668..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmeI3c~Dl>8^QfZnkmTjh!TK1AH6QgCBn$Vb-Q;oh_ zX4-C%ZQ5S8lC~I8nYI|EktQvYqCz0ydw$=~!E=9?R}fJV{QW#LU(UVnU7qJT=UL8q zo{Q(jc(Gn$qNhIIo8QUvdU~E0AHV&)wdbwYZ>`mHePlDw%hC;9b&nqLh70^|TgR&I zz~BFm5r~V6O91<$wDIxrEro^RAGF-xWH{=mqXvopvh5hOKk?t8Lx*<4QpsR|WLPS+ z+h1fj`sky_ivLK*jvWn<3=v`M{=k2yPMx}o=hck+%{Sj{p|LlTXSLA1Da+8MOP7N> zckVn}<8Mws{dDvF_upHbcG_uHkHr6M;h?4}gZS?wY}6c>a5!vSn?8NIK_+3N(5ET# zf6Ot*wCdWm>znXCV88%VSXk)Tx5pP;aDklz>DHS7|!^ z-rd2AFTQAW9eds?jA%;yckkXk?$~3GT_)WzBS(%jTefU*Z2LXGg+d|h*l3QH32{w9 zh7(UbF-BuPN&K5rPd(Lq_St7X&(Q~;e)_5D(W3|a8`=3J$s5zyG9)A<^bpp;|D;Ki zOl4(dG~50;*SJT#gLOiW#^nEm6HaK6n3y;Zo$uejzge|vmCq{&KmYu*S+r=8dFP#X zEZ%$XJ@e2*4;ejU&^2M6(4w(q5dQ;&ErNOCi6^S@&dDdAd}4J<_F({X1mve2w&-|3 zWAJ~{Nhh@ta*jX#cr$F+F!T4{fA7G5MMZ^~GG&T6^UO2NS!bPP!7bU$cDqa-YX-+qRjF8#kIr zB;xxf;n3*$YR^#=jpMEm8-+sIK{rBH@ zU>jTb;fEg#JUc8~w#?jc!wr^y+4p+!pWKlAYfafw`o2K?n=7xp(xAt#{rm5~)>hG} zhaY~}{p|N!w{A5PCQL9qi_H-00Pzg}3naq=p~3c=XPj}yV98LHl$5l?8t3!RKR0Ke zeYWN2yz|a8D_5@cd3Oh2e)*;8*RP+?JNzRLbEz1J3}wRLhM0roo}O+t zZ{FIXi4$&w|(+je@qc=2NUoOq8Yri|O0{EM#yp#UCEyt(}7#Z@kfL+O%n>e7lRhbK=B_)(*sffv{KdMv9vU zX)Nbx{LN*TU1sOs(Zo;Aojcd=718T2zWBmkBA#(Sd&sArddlu!u=OC;u3c;X`s=T1 z{tKJoJ;Zdak>&_{yw{XX_LU69=);pwKIvGuJ@hWV_+mTn_uqfNzxE_HjT<-4C{Eb5 z!i5)JXdKvw0c?E8kRjHm249NrVm&1k3w`%Qk9zm+-CB4X-mkmvI>Cij9LP5S^aP9;F~Z`SYpyX4ZDjY4}^_S94S;jH-!$ z@!mzq$EQ!7I<;C%X>2*l%gb$?)7TR;@`Wxz8N_$25Ju;Tecyijt+gZeBuxR>H0y2g zXk(u2B`o-RP5quC6v6-HmtSt7%wWD5iN zV+;A@FpxhEi+?ah=n%An1IGtO;J^s%Un5WzTRm^bK9XS!zq`INrRv=E<#AQ##jUFM z1so);JFi#@Lu=dLgCyyl#{KF9N7InVUG zm|*XzalXA584>h6krAQ)_97>Op67az5kb#$eF5jqJuin|5!CgWoNI^TdSjdD)zR~v zR=kiZ#MmPpv=;t{n!ev@2O2{p)mvlr{X}>>{58+M;zjh6MY{;-n~ny}k4MX-I&DkQ zUr4=>oS1l6C>|Otzg+|UA*$7vQD*?+rA!zSeP2VIt0vc8v~$@DktZZC#a>rqkgIPv z+BXEv;5$WsJh|YPUw*mD1?ca>g$t>bL_~jl@ZP70AiqJ*gWR0vXpw5Kd(GR6ewy+G z6;D6?v?J~JKcja8Nw~(!6 zqjTSV_nnoM`Yp8u_R8#Amo8oEj{&*PAAkJO))yHYzA0f}EBUkKujBbE0Nvu9d=o;xkM9_3`Xr2)|y|7rmwLbt$p=2>W4JyAk;mf@8$x# z!wX);%X=4N@cs-M1OQNotn-?x2xpOCr9GOmU<;Q4L28-Dg8lCYR3*= zef5>O=bn2Ed^md{_f0Kd{ySfG%(ArBraVKeatJdny67UmW=H*jc_yz+O|q`We32_7 zx9R)^by;j!^k--+YF(=-w~;FPMboBD^KFaq({I+^h&$*!;Cr?ppaHl>ehV8RFH0j= zclX_QL%&G$Q)?Ok}OTmwrzJB-=g2ytXZ>IViIddpmoYj-BW9Pihf@Et<+m@y|sw-FtJYSfui>9 z+owj~SJU|sM;u|}4Y8XTOUz@vqd5JF#-h%#)Oup5{(qsIZ&HYF#9iW+zJo5;{%dGW zG~I978yv1Um&aa)?{KKe^A7eG#CpYtJiWvB&+a+b%ePGATLJtkah|mi>kR%k0UjQG z^ig8%M0bC%m+w#1+GY)FiTm!m&wfkHw?Y}JK~Yy{4Ua4u%Qf0hSMyI=OCK!%`xtSa zSopvL4_LmT%{M#vch*0|Jz}H$;A4j#dg#H9zWDC1ao)r?7Sya*OHy~AHEWjbIi_Z% zIkmA@Ylcmt*`MbXFWRW){w`~4)^@~m=((8VVhla&aPHx{zKwcUW7$T&J6*A_c+Q+T zrHXT<8Y2sifySVeYg*%#YMoswo=O#~O7;Cgv0`?*^gBWCNR}^8k}tQAKTnbmPf{F7 z5`Rg$FG+Kkq%}^G#y?5lx$t|k?%CsHqUpap4EYD;eEZUh9ROHx7_L11s#v`Pyq9ZET0Wy65k*O0Dx3YRp}l8K*2{S zKnMqaJaA`l2Y(Q`sowVh01_(PHw1W-ehmQd1)U5`JWaGTrEJlzeAaeo8+$%qS2vIv z0A%ER-K=e$?L84T_79y#J z6XdlO5D-L&gHIx2LK2daJP08HAz^+2F@7OYULgS~0YNEIQN+K$SU_AjB^u#0ygJdibF{t$le>9<2YtLCN03 z7USgR>4Ziha2%~|&|aRhETF3YnuDv`KWtGR|F#ooF@9fbH-14r0o>*^3jRau=7{!0dpM&1C#?T@{a*xtw$;-5N5+4vi>vEDB0M~m zy}@bx+aUifwTFS9n?3(Mdk?f1#@1fh8&s1OHybx8MU1_*CmLgbM!Wonr*!{AWrUC@ zp8x`B?1ZvI`*_^?PXp|gtUc{zS#VzC6%^nV6fqDKmJ$_~5)k4R5RwuQ_!p@b+Rn+r z@4u1?2^t6qN(qQci3tA}QV=tC)}Ge?TVgv~DF-yh)f$|zldJVZdww_6Ll(q8W|UGy zyPz?kU{E{3zglQ%NvWYcJgrf-_G(J9Ea05^oSf{WY-~mBBpt-Xc_r*^ZFoflM1*)H zCB+1Ig+y(vg~eBt!&lC3yuUY(#k_ z97IHTB?ay5c?Io-Y=lJxY{i6Z{?SGU;{*npwab6ziqpytf`~s&hOvxp>Oa0?b_Sr!Kj+7)5#=H}vLYmJ*Lzcu8O7Xb)y+eiqzh_;IQ1U(VgQ6nr}FQ)_3$8KY1K|rzv-{757&D-9P$vHr8LxG{Ekl`a721xH0#9 zt7KdH!Ksh=?##kZ=g6ODhW@8((!7DEe}3>Ye_JbAk10RD-O;@=+%$OV5%GF~!T2fm zz?MG{>)!E%nr61%L^^ieIImE`a(%YSq=9y!di~?+YTf+nVL2LS71L6ShT-)Gr5W!I z)}_lEPnT>@mmE;b4ya$WTV;}zbtoa1Yr4SJR4{#AFqL>=Fc5qEz%n3-N7gv$0ei#| z#lm)RW-wzdW5V3^H#&)(F-=>XMZUv-vP5Q0A7S~cv)Bgup_!xpK8ppYEv6@S1m}c- zr-aSalwR}^r_<~^(pdIn#C^3Lef-zk9CMzD)onYfU2WBh=yKwN+O{_-j+BbK;hZDs0fmKrDDjQz5+% zuY#iEsYN`RKY}|ZJ!fE860=go6Y|h!3<`;gPNtC6GPSjc@(j{;g^WN2wX5sCalbS^ z7wN1;zPwl2^wEU;XI%zcFxJ?=?Q2F|19g4teQzjIW<5E;bRA`*hJoOj2D@gl>p8qd zcfa^{Ue7omFQ}H(x#INrS|AG4`?P&P>!|DXtH|M{W}!6ZJ{rI?kr(v|)7ibNQ{BIVEbu{-T9 z`)Av27Dtm!oi2D}l@zUM^tbqvkO7=8Q^iL-V`~xjTp>FbrLDD|!X+6QFY?02FdK`5 zj|h`Wq&bD0+^z}u1Dm0DM-1hD>C{cd8aevf) z!=l~g_xO@*yBZhA#~;VS`{Dl6HX#{_@eM9&RL8#pSh74yJ&j+s0aOpCjaI!s{SIq( z%Z^1dW(N>cJ-nLu(kn|1mSr97SGD;&|HGcu3Df%FmoeH~ZfW^Ut#2pQ9M~d8r&%Eu zCI(rz_{xHLz8M9Q#EVD<+bcs~w-WPLTN@-y1<IqAWegt+Hc#gi+t@z8Pe!WFUfkM3QqoIiIbfoy|)8w7Hs3 z(|jcTXN_vOgfxN~@98;g9M~fs)RkYTIT`a(o4ZF1v+d#@H9QH;y?kbpro;t{5gDy@ z61`2MJkFb0MZq&q^i+D_3|78y3YGVQki5?G<*}U8I6(~zSxaXA`)@HKaP2<@}4BUgB%#Twt=?g4hHmvM?$&r!;_H3 zKc2HiuF(#5aJ~3>rAE(O|3|o3U;?tdiLdV4{P+((=dSC>xw95yF-dZ1J<6u$=NX#T z<*}C5Y;TOJ$ZlapXhUTSMvprroLnFhl=d4M(C=l<$jGgkO4pF&S$E5K#MdzJq(EPV zVi;Mk4bk!vsme6fzK>W#fG;{{)Z79_opiUdfk zv`XB^jI{;N7F>VHo0f39npFAbn^57In-Br7U|kNjTCeK)rF!Eq4E3^UBOlnqX@vM} zuI>$!$Wu+M5mJ8YjmN(eu6S#(Mu1<>GEhq_qOd$I0!mf}-=T_!F_Y@ctH*1T(4b!R zTLw%=pS+G#dS5CPLBHdVN?`n@wRkoK?_1UC)yZ+*IcOG-sQlUPHE6q4fLaUiOI%{V zHdGpqp`qRhc?=z4u9u&|Dm7W22kg_)-*$Hy^Tl|GpXG&A4M(*KAaf zBO(J=!hQGn3L1ZB)*$AsD}G1!1%%7DxXu5>%#GE%KWMOFDRH;T;M5w&1GC1%pI56aMl$Z5e;Tci}Gs(-9@J{%j zVFT*{DmQDK3?{#$Hrh_T4DsFlR+b!y44+mYc#jzRpT54Ui78|pT_kP19n8I}|9D>Bgth0O|T}EiU z!?)@gM0`cF6NEq#?1xQkiRDJR4}_ozvJ5SRaiU`UhccsqSN@?@!&XQFjLTUHptj%K z+e)qvL;ckrt52Ix=|F&Sdm6LwRXt{oVWN^E=o6Zpi|`)VA_C9RZ0=PF;T@0F33Wi% zp*5p^=fmpMH3kNHEy(HkUNrRNMT9R<^%%)UkeL#Bv)AuJQWc`d-hET;q7597Q!$$V zhoD|)i1mSgOc^s88?lj{eI%!Cde`vw->atwpDFcJX ztwU1?C5#vuk@q?Y4qrtg8I#MIQ7jNP-w6Si<5_Y~hSjrThiwBejv->?`}e5>~j z!qS$Qn?dlfHlufel6CQ6Z4wg2Hjm)N4Wv9d{O<7VHF~x+5o=oFg*igr+|W0f^z+_v zwYQ^g0u{PrLuUO$N3X}kUxY457jP_UQTcmsDlu}V5(diY1^ zU*6v%XbZ;z{Kzio0v1Y4pt@g!p^LC`X;Bb5Zgn?wCLX(HFMWa`osM?lJHoexTSsrZ zv^)2IrYNnx-&BV`y}G@N^WMlt>nvzpGr6rt3r=}refSXsQ<0p2VUEC5;w>-`Brc<2 z+ZzamiAJqRkHhG)mYe)K(D>bj4N3QYqv zMC9G3-rWQQgypZ$XtxuQgt@ytH6kE4%;?RII7|-*=9(33c<8#D6&NOO$H>x%t^syK zY%D>A%?iKxMdlAy#{RfFRb)Z1wsC=4$iY;(GMRd-FnN>#I zGSjE(z1hl*XG&RdbdZ4-49_cTL3Qejv#>7{V0$zECe^&ahNW^CH zUH&%q`4ahCpDlz*An{|&v68aqvCe^^J02>7CZJ$Q7mk?;zs?(+`i7Q0UGGU+0`Llx zjnrVG%Rm5jq;$Uil*3%%rIj@YX1Osp4e~w)oT_7-Rj5VMmpw3|m8m7P*K`S=s;U82 zv)T89`tybTLuVSzg07LsBi5)E@mRqfxlAP zyP)YdxAVOoI6zBG&o#*uc!3gsGMk;6TN2NfMh4ybbbv2>NL-{QL9-zCwmhi}U72%K zm|ay+J4orZ6wTDkFtN5xQCf14`3A@(4huu~pJV1!MLXb`WRE9y$|CNiUN4xoe7A?1 zn`P^uRa(!kx(~lh@^&Sc_tn3V$uE}xTcZ~t^OQ(@V?*#|Bdl#X^EFq7(-!wmTz5Ou zwNa_yO~$lLtI6T#2C!!d?hma~dN3|JU7z2YU)-&vC2U0!sD~+*uCXlgQ;TU=T&nF4 zDMz~$c?znBegE-sO+747{%q6sDbb5@zPMzWXqtV0+6WhT_RXHRw1o2G;;PWb=05jN zORX)WTzemDVk?oeUVX~JkN8hz@Dj!@3CmVOIwxS2LPcDdE!pqgh0eh4sk7d(1=pbCgn~PIYR<^(psl_UO_@n=47QOV`PCd?C#A zRd<1}pRU*51>zVa#Ag{!&hVoXwDgJYzMFiyV>H{~E6xXn{|LVzhvF@eg=D=5KPVV* zR$3y7ze0Inz=)h-f&_)NbwZNLu*INp!lYht24K14J~1W}zcNjtmdN_dY`|WOW(9Wh z4h0rt3DW(Zs@=nI)vm)e2gFrF!~-tDvVcft5gOreNKfZ)UrKuOvzIV~AmVlZs2>sA z?{Mzr)ZWo@89ip>G0)rmSnmkJTQ%YlknH__HVZel=+zoUE7i z4gri}{U(GUNa8THGR|5J%v}B>*OAVT9ZTeSlQA#mh1teO@T-koeoN&}*byDyN-%u= zll`3{d}l@kw-(SAe3x}|r6!gxOoe~2W-B_sI2`(A@{t@*QXNiXW35X`*j(et;q`v9 z-*fx7)3(fh(p9+|wGh-Gz4-Uz$p{AI+->741s|_P>1m})ubmI-r#^_I_T96qe!a8z z$UQFLS;5K&#qAL5#dYe&RR9u{3K==CJNFNbp<&4?L^p^)Gug%vFRY_W<>)3XBp=+r zsm#N{(qh#0n0mY>hvdr7hSzxF`c%nJI6H-{i7s z1jtu@?*5uNo3$_6vlgCN)F1Y2cAtv?H^G@l>zU8zzwCVv78bb6?`@yhJz(m80J&Iu zaW=U5NNM%##mPlk1fi+SBJ1F#P$dc2XPB^z-S7+t48q!!dVhZshRr}pweKW5&Gt@5 zn;Fb4@Ad!bkBnF`YN@}mm!ITP52qJ_JFa$awQEiL?I16@%FZ^Uf4gMwG@X?=+eR7W zn9UvfCOik^C3jlu>cOx-RG~REyJTv(ZyY1;Ggo%TUF@L0grz|()AAm;Ow{b+OG_%h zjb~hD0ax*BnM6hpdO61Vzm7FxWxvT>=)d}g#0HEqR@!}m3g)DC`s; znxJ>RQ1mSPhdEIZr@mCr+S`?MKgR3Asuo6aGtRQg)*IjINL;3}F^(UyKTjhaR9MEtVF zXbVmAsp7%#&prJwR1&Kp^v4wzP=S5YpGqH=K=^$(zr~+{+BLRFdUE10zrQ^rA*SpG z*c_jYYPv+?3jcjAUX+k!v5H5bYy8HwPGSm-7s0pRvrX;~ONmHb0MsOB(APWGIlhH@ zhu=j-M=LZc_cG~iDE_pwV?-2Jhy5}X7t3@SQYB~Cc zGA^?tosAJ|@zMHW+A?MwCw z3J@H-8WRF*^q#h*;*)o0vsuOh-tviZYS;SmC~Jp%oExaIGVn%WqYjd99vwM>q&(DO zV#$@={vKwFtqM@#r_go{gZDQzPkzrI)4w>1Tuaz(mVr%j03Ndl$XcUM33?z~P;!9j zLT=f7z3`+ZAduC5;^yd)S27{6K`#X5JfCI(RLP!}r5KqgU!L=or+(^+){1PoB7t3#^Y8pL^4Z;KD;8dc?Oz%n z#e=4dp*`%PdwB_(i;2Tt52oy65R|v{9`gM>o9&p!l5dP7YJ3wawqT_rgo*SG@ zKj)<*rb0uu{!pyLFb>ONvzq6>XO2x|TwV)gA7K5xw!A`txjWV`eEcm?&N^gD_uTS^ z;07v2I+-7JFXw)TRF;Jf2Fm5`aw)AEPqTq#@!Z!bS}7lg*4c@tXH}^Xm1R^DNnb6Q zG`Mm9fp?JJR8EQ8?{e0>Qvn@4=DCUPH!qE^1ja6F=`JuUxak>zJ`6Hv?% z2!5L9YTwYrM?*Yl(M@rFognyUrq>Efi}5o>xr>fT+Xn*SI|aq2o;x=sm6S&|Q?9y~8TD*xzI$PryMm8xqb zb$NW-x&36MXm>d#SXxnLQnup9)Pqr??BHevdyVYPJJz@KrF5u&>m}q|lT^9UFISVt zJ3DH1^L%nma+LS)9y*A~(ti)z9pFdumEW>D`h?!?x#>*e53B`!Aa}8ZqelICvuG|zr5u{gP-z_$CNsTo)`T^iz9PP{|wZLjsfBSJ(jn%oAadU$^1C8^6* zxv#8O^boFnMEwb$K`W|(oyf;(2HuL_R($Bjhq9==qD^8~@M9PO3 zF4u)1L6|urD=9-PUto?vV7ku*MQo_i)dGHj)0U>)D%#)M{QK;m%Wj%?Z?cFC)`L58 zH_3_*^F(T0)Iz5vLf82;0GFL~(0d~a$Eo8#5ufKRT}#hewA=%3as_cq;`L%txLtaTL9oD25FM&^*`;IL z$y<~IlzHKVCg)+8Q~{>BFim~ERxI>_eboZz#0BUu`4BIL{dK^UCRr?iwdKNob%EBJj*%_ zaW7kO^P=q+zE7T_ejThArCe?|&t+Yb2i2qF_~x5?n-%6aN2PVSJG`nATK2X}((2oy z<@CA5Az{8P>%hDW~{Od=RTE-ujAhsUX32# z=j^iDzBb_;IX-hk2{qxlU4SvQ{3Tqv4ksTLR|O;mYPsErz5RD@T|e$kZaE$;KQc=0 zo?o)=<#6Do>3BjmM66+2U)VrrKr-Cq5a5-C%Q?Qf_6_=Wc3g|WvhOv?8pf%z9KOli zs1atZ=nKJjcr~b#oHyx9U1H7%8)p{5Su27G_xZBfu_33S8f&#AonR*hlF-Q|21SJkb+0 zg!aS8o4z-8;{#PRv6gMxNbBN(_=(Z&*ea%C;ftv?0*KN9DY32GndwQ^Px_dtiX|dp zr;hTMJ|DvZ6RwOT%IPR_CHTehhL-5x3Ji6ihhlsUS%X?8}HH*MMsV1VhSjf zS;*}U8w_7vJ>L~8QLy^1OdYGkleFsEQ@Tb4*%&7dyNS_|*4wikkfM-4HD+9S&g$FC zgp}D5ly=cGVS+6zzP94L%cvaXQs3)3g&U)^Puj+}$#T|R#0$3w^w5ZujJZ*CB^jv3 zGbrnm(|f%7B^58X#?-sC%o%OFV$ec3_fXS8evGH5#V1p_tKt1^*1+BOFvB}B$UIph zZ2^nys*!k3eCf_VleQ%!rz`>5;Q1_A!Rdzz-V)ms_1h`s=*TB|)X8jL7};7yHx zF6C5mDcS3(ZodBGKmXy$$IR18YT;ru95^EVDCqwrtWD$+d#dI+BNTiR8mRBMOzGL1 z(@glXkDfe{Suu&DWqkL13w`wA8*ac_BvDfq&uU&YZ&cu#c>MJj4iMtSQ1X-jrQc6> z@X%MM+3tEh{?T=gCWDCZ5zN?UDn))Z`BamU;wxeqrExWyZ~(=~#&x2qqX4U2?_1dD zA+TuMUZw!dk(&C%cTAIi;49q!_WllbtuU%c{H;FTgzD0k<*VBfo;O<+#ofg}a9&7l zx~#E6kYHm{sD3z_E}<+>8b9mLnypSog?VXTD+AuAdj*_MhC!BFI*oz1#`{{f;lLs3 zjgiyW9o%~xHFe2%joxx;+zdqSDg1Qe{voD#W7HyJbv0JE@Cg6P^oIt`1=E1LH~d{l zAo8h@7SdG6&&NX1_FnWg17|AC&cSvu1CZw z@WsrOZkV>>Ow;uC&n4TK&(SOI_|H!^^2oVf(tebIo18r_ck4ne7v!@ROLz0U{aoFG zg=Z(gNhqTIP93aqt*!d^i`{VA+- z*^2=38Iaxg(p;6sNUnw5_D+-ID9$$9^$x82wKyve)ukgIJj``v?IJT<*b)mkYj=RPJ+j~Bq?pq1#s2(1yV8phR^WPi3el{%oa@%aJK`VK( z1?;JV8<2sps?+qT5|zU5#&%fLHf*7pAo7^GsYT5MBe0qQOa0mtTiT2_!V5#Q zH*krGW{om^^MLdZRhJDokb=;Z`#XAwm3SoL-P(2>|BCy>jX`>cgeX?!N=R4u2P8Ze1l z+UHtqLChwz*^FM%*35dZL7?~5tUb}kQ61OHf*yXy3T9%~u# zrY}AsQjPeH{a`lhAy-3`b{Ll3tUzMBJt3C6eW-~}+H7}c7Gtblh?g6Q)(|$XL?zC)_w}$G_*z83H^7eGp4-cnpNuG$m2Cn#ricDMk zn5AALsU@|wBf}bIWE~y;M5_TA->%e&)E2&xj47CBa@my7@pQ)OXrK4~-5lkur`7$U zZJ%FaM$gP=d0CtcEn{goFT}`$a&=Sk`M00#iJqh&zXWJ0Ogv2gGpPVXG%H*`OlSDK zJDPq#@a}FCx^}MC6`uVHRxJu8?iz4E3Ny+%!gf*fB`)Xf}JRf&|O4Ggk zvLHBYG{(z$>P-nYvK>p`oVwByPqyzG&?m455AXBzr zTRx@Y$}BBaP_b^xHBG(lV0YV`i35Htv*zWeWwu!q^!TM6zKoGljFV>Y4r~~7kq@qv5zwbT+J9ZpcwjDUrfx5Zn2oO;dl${#ach|CtrI=4qkT zkqtlVA<~8hEw%aykmi^33=^$jo}F{f+_LoNl|MnZf$xrS);uSHx25UolMThH=ua~% z@5>DbQU>t}&yjiGDVu=X_B}k1Fcn(EOS$acXz?*RzX>T^YE5jd=kFoYpA0ul!Du2k!Pr$;#_KmHy_LvFt62hBI^y$NS5R%Te(0eu2>0od-aP5!*+Jfrgvli zFcTr(G8B?%$M+9VI}n&IwmdHBc6li4W|IgMXK&E6z1DBaWHLcsq30xCYT0;7c+c}(Rb50;(#Qu!nnPR>bi`-be$E7-#CVV{8O7dp@v1ViGEw3?*l zU($uAq%TW5?h&dIS~aqR>c}@T)IE6n;E@f~i1}fTK-O0&y!y+LY6pTPIqgT3@)12j z8unPL-}bZFVcb(=G#b|$c7NKgx6mhN3iDkopZR=$e{#7ATq!LlZi0I7=}6|Q0WTL@ z{S~97lnWjcj4XWkF?h4!kJES42ya`Qa&eTPhXkoh$bF_rpb}*GQbctRl0&`O$cI?f z>#s{Fz{+q6tEOIevopDQb`QCMw()HsoRc%JIbF@5f&Zj#qmmc%WJ6C}^YLii0sc?@pR?~KB{{BQ~)q1S)$f9=?&=B3zHGz5V^+ zQtNbKoMo^vMz0Gfz1@eKk{DPiQNA54neGYluy>KG;oa#txX*q^VW~xbrjjivX;GeJ zVuOBv&D#L4K}5Sj;vLHqY#dPk>UuU=K88_d!!fq zdGL9or5f-XazJ`&?~Se=7B4K!NXd1>3uj?&Ptj5ZfjA&7soN5YszeV2hVQ2b8_(~* zUw}$dhBXDM0vVyXXkClzyjdIr+Bp^C9xpvKKkK|UZ^vo;pgY(%wP$)n2u3SfcXGaW zaCFqtY;0iNtR!rMN&I+BN0jXk)`~AbugiL+NzXhIrDQ{q_oUhF%MoQ;Prda!pcSs? z_Yb|7M}I=~{QH|W2o4p2OY*(Vk3W8fyV>7$ z|BC@8@OA_q-nB>5hbZdeLWLX5_W9>|EASm= zUAcH!^8n-aiIuZwY2ZWG ztXMA^{Ky>rOICZ00M)d;+1Q ze~VQEWaD7LJwfmCRV8^Oj-5$2F|*lil5YH!5{gR^WiDwa(X))H zmn)B!EK?`tL0ngS!eqbqE%0Tp%FzBAjMn&ph1!V+JRz2+563}#W?r{4bVLFwSD;5n z9F~E!x!#@g8Rz6|hT~fV6Hv#Fi_M_(ccTK-e`a~NZ&J!Ixe?o8 zCT5v};2J*g#N6?UQ{!DLx>Nk#U!;+ON%5e@R?>^Dx@`VUd=--{kf`*sLpdCJYlynR zcIa;rSEti{O^D{d#I2IPqge91QIl|e$JD73v807t{%S}m!rI_3u1KJQ0S@_=Sp`k4 zw~903AlMYZ#@!k~?^LZj#;AF(q>H#f&|)tWG;0RKF}3+c{>LE40Lcp7#WQ-!R9x;B zBLi;)-J({~KZr^XYr8bi_RaeUS*>WCySM`#laXO9ucn|jYGArimBuSPSCVqy>lbGB z!#&Uyx@1?%%VBR3DH>$y#n5Es*=e`7Ct>i4)Sxr`6UCr)qX`Dg94i8=W^YSXk$ob& zO-0$d+znZuY=;N5~~@7Z*SpTP99B7e3t2=^*vbJSxp@(20YwmrUW2|q>sa# zH?F$yim^rn5~UXypq$k~&&ju9=B|)^usHaVB`$G+^$ko)(deKi(3MeWWh{jtGG9?yx6LOzLvo66O4<= z_F``GIM{X%H;M{u){A1Y;NnP;>KS+HyxXe<%x2$4~c}}x%UjB}|PDKz_bI_&lfS>;4PU1y8fE%Nf$AApBK^W@! z?M#<@AtJHTiJa+%y_5m`kR@A31%V;Cs=#obpta*Iv!&@pZKur^|k5I3;$_i>xp zUaQ1q7J%ge*;51U&sF}R#9@b)moGu!0xWQ_(KV#|L{4iq`y^sk!OHS)Vtk>5nME~k=3i#)eLuei8-|}UFYUKnX?*CpkHvd0Nfcz# zDa=B!^(G4A>d<<+k}XQ~9JhEOFyDerzQ@IOIjqfFQbviGV;TO6Ho_Ul%05Y*AHqd& z`;tWZ=fQn1)ugrwqzf@#_ z;1)0W_U>RS@E)K15v-y0T&D1r044PA3^c*RGJ~v#bNHW|6_PXOEU}y++MU7=Y$<_X zFax9uT?{brHQ4e8_TK%4(d3tPk>3KZHa3H(y9$=?jRmr*=9!lwYzO|qTq8>#CstKGwY?=c*?tf<&^f&3ff~|wib0Z|t(n`>u z*<0^#5d}G_l3h`Ompg1Gk8T>*Qkkp}h*ksOAh^5;3_Lvr@A~D}pa(u!pO)leulmWV z0ncc`Ge%bZsmoTzD z?_v`{r&Ih8R~;(4Gf#@O;DlEk_2a!~B?_vTzn%Ysm2N>_qY0GA7!>dtl{OI~ zc39cHHz4mG%$)hsc5?MZ%U9=dTq3E0*ydF1Jmx393L0lUa}=~sUJ?vqJZIUzNSp5u zt{-!^Rx=oUOVdYk$DkEB#*X@A@H2chSFb>xKRR5Y;o&LgU4LWxX8J@WY@O40m?I}b zsNiq(A1%q(vJsGJR$mq)t#Cyrkn6>en+h>alv5)1z-gZQ9+T}$71HL3s|kTz?s9pg zu)Hw^(tvX{=5O}O0wJLz7U;NS>E9=agTs%TVEZQ~$MuDQ68^?tjaI3%U!;2|@@8|D zKzJ^_y4UYO5mM{~OiD?Rl66*Gi7a15qCbn!lY;*(ij`Dyw&?TtuW%Kf`}D4ZADEK5 zMR5A@EH9VGHx)ngFGxJ8!NnpqNAo!O%GbY&efRDB2>UR7$>m+K8u(Z7@0dAz1VbHJ z;59IjfL4+Kcf)w;$CXpkDSwzh>sL@<=Avt1x}uDrjtbCK*xViKTyj_}NF4_}W+7-s zVCHmbprBFUV1=;QdW!+d1I9l14iCJlNTdWrftelwami$mAi$Fc-L4Aw!%UExA(U32 zso-EKfXN2?Z|&WIe>27@7r|)_ID3%6X#|~!aJDwYYMVI(K41x6TnTtm59>!_DZo`T z8CEhGye)K^g@Eke(DM%kSB>W~{h;MnFmtE-1WPSunP9a4umDf4{1;+=U_s?zZoza! z6t4TsIO~5P!eo1p)Pl7Wf#VjIq@R~4X!SM+857C7Ywu)g*#H~cMfoLMA&Ph$(u5Cw zjA`XHTz((V_~kpSXg?U2V*--oOn->YJd{fEya$02UjNp zADSkEgfmsZhq6aN6PWLFN9$rzE^B2#(Ab!XLq#st02w^`d9tT^+Lv@A7o4go h;$I(|n}=ZudY4Fl+TT=G!F{A#O<7y1{Ek(~{{ zXv&gxhGYvPVaW13)93nJzx(lh-1q(c{PXRR(s;jL%XyviJkRqyuaZw#neuKG--<$^ zc+JfYpF*KnjF?|sobbtq8+k?W7q_3;*+3MEN0|A=g1Vn2ib8SBd)l4}I%9cU*9Gr` zc6P;Ia6^ar_`%aCl)hn@pRcaQTk1=wxzaI(mGLSQ7 zPAGfE@`S7jKEO>@6Ro1`qN1WEtEGch)jW7mQ{{lHnu?kVMnwaos-~=}sjG5OS5-^) z?_Y8-TY&3D-BX8;{yi7`%RtT}D9BG2g9!}{MTe@R@d54_RUI82jEWjYO-&h|P!0_D z4RQ`s_6?N(_XvmG0$l<;{enF4zOu{_oiE^ngAC+grT^N3kKaGT`Ud`OCNLN#%-Ij4 zidJE6>E91pTK?~k`uP0wbYRet5SZof_5Qa52ik`FxnWMZ1>%DPT-=U?xcLUj|9di5 zmw(>%3l8x9y;D~gjGMQc4?GqK3se1PDnAc=5I)cY|3B>GpCA9T8$Vr>05|6#e1I(; z@BQzCI`QvOWYtvBYO?$6Jbhj9p@I9EEBgBdx5LgsZU%D9Q&U#aQC8EjRaMbdQ`1$` zR#H*ZRZ;oZqn6+YuFgTu|JlQMSI>*#|H-44mb&J?fkDo`E^g+B4dh@^Xira9T{Rt5 zSFMX$I?ApG)isqhR1Rt@Ur^J~R#wy0xS*w@t#;7)g68ja!TX2tF2PLmG2j1}+q&Xi zV2pn(q^qN$p`)n=uB4^v?56Cjbx=du*-c$XSw%}rQ$tHjRZGiNsrDbqu;=0{94RdqBq zmDSLyOt*(+z;?|%1L2Ir{|+P@H~+uC^Y)be?VY;LF3g}XkaJ;rgPW_|-yeJaH)j6N zHuSGyLp|JJ(Er6t{`FWO{$fz5bAX$%I~>XX)eABI)8Yf2L;m-r|7RZZ|8VJlo7Kg` z+1K3-5EdiH+zf_^MgKY!%>Q{_zkl{$aO>ZX0~j*D{Rf5NAOGOEn=cF<04VLsd7=`9 zLbI74Hnt7xn;GO;yMCJ3=AUx^c!B4oiQL#sMKZQwPF;E2JUaSUcz56Q+37FCiIn2aRr+c)i*y>HxyLfaLKx)2pYW+m5)hLJ&F=@NkOT-5oK{rQDuEA>cW0Q z_5Z;G>^B;?|NHUp`J#&L$~GP!G`ZjUJ#;cJ{afy(t|GCSTNdb#rSM(f>B3WcLhdTr zrFON7;3SKW-BoNYy3l&{X6?k|YjUS^4keh~#o(}~#{Rl{&GySnH~C;%g2-&C80FeY zl*1mkj6wFotlekCEU6SL_>H=jExS|i%7K8`GtbyxzU97nQ|P_i-bY7{8MW&+9XJ(x zPP61H>-mV-!;AnH0{0pci$O=llSL6@5eGlxU;9wAdp_*3YDuH#@e{Qf;oD^HE6wci z6h2JUDHhyEGG%b#N~zbb;)@w2)QyQ5xo0_9D*ek#L3Vsc#(;j-nR2!C6=^3 zm1ra5NPHUoOCsi5S}pDMu{O_awmbMCC-xM2UbuUY0^(1XM{d$=7AaUR<>8iJ7VXJm zG}Xqo{Qi@&$&*?(UD5pgBmbrR5cmHMk$7~iBy}x%!Tk6R^$DXUN%oF zyn4_JohJM`j&nox^-t}}oUDFQqou5yv*Cr=d5*GAxidAW*O$5!%YFJaiQ-jNKRjp=MB_Nl8hXwQ z#WQ(;TQ0`HXT*`(nPakYl{)g*lf}Q3$|gt!mvwJ{&NGYc!R2bypt{R&hUFJOh!YiI zfb%6z^}5>oA93Tp)h%?KlV8`k{k6o8wfBR<5C?XHF^ahP`HwY`&@~E3(F1jJ+_n8- zckd7>9M6wl7tc)K5&6;8)OvSB13y%UlZr^@mRUWfILR9Gv?w|BO15tBh*JDDrPku$ z>FyeOVbQTx2Nr>PH`XS8!?hb_Lg>=%r7v9Cj>eX8tqrk8m9m7TR2&g$%(r}S@wN9C zk{yqT-PP`IA0DW`^6KeM;P<(k>Mv;YGX_SEJco>xR0M+=)fkRp+1im;ExOR_g`t4ts3QX zWW=)9U36Y^;1C#H*!#f9@7w!KWYNz*ypFjRR_wvEiZr&E34LMIP|zpKOewt(`stR| zF>_h*Foq8fN9yAo)j9XjLMys|YPTDVr-ABHEE?L(u}x}T(Bi+BiA zuSry!YCbBKa$&Gm>r(f#%$22n{7TWt$dB`p>x(^23&i{MoK^}pp=q2a=4op3wWQ~F zJ6c=EHb@4B_vwY`VJQU5^5>h(Du16JU*93Y{{A|33db|f!@f%QF%UNT_CllOqIX`U z)rq4E)m4&?=PG@96D7Pz>4Lpmb8RT>vQsW2se_wqQoEBabbJb%eOz5!umh-F_`jzloa;WYgpTsVIR2R>zo zAYYVWkc%cgoQ;a17alvN9>mg;*10fFw*Ja5zAQ%ds``4%B1#y2`C|!S;frF2>VWTP zB4gw&tzmxD_Qi$Px6b#??kL(m70_{@NaY2L{pIG!#Ki=c-Cq*9+ZhoxAv5>iF1LLD zQXa=f1_NcDdgnbKDBkEu<*_ptX#~u5>#M{Q-UgE3INx(eVVgum3`y?NL_e(ozqrM@ zEeJn2;VBX9={#>5yeCJusTUI=`pq?L5*H2WV(J$Kuv=)?;&5o%Z!Fx}%pW=5D$?B` z^Cm^ig%$hr;&w(By9y7(*3|sLD5>Dm=cgxCF7+=>b(cs0!gVwz-3mK#e)P@tCL4QL z-UrIblT^LwXXUY3C>2(OR@0V%8Q{UxonPmVTKO^7Bva?Z2m-8}jOV8HX(iEWp9mHw0Bi5)4!bi|_~xb6jbC$d(V>=% z&SlEx;RFmX>hT+Y8c&jPSU->9!Gs)XTb)e z+Vnh*#u3V1ctb04HE0?WJ3rbcOx*tc`zjZq#$jzRbokXq4M8{f(t)**EBujiJJQ&2 zim2^XonI7CE!P)Bn|yw8p;AZb2V~MJdgHBWp@YFaXAQR|&b>(Fm6#$<+hj|LV1vG8 zy07w3F^s~8Jx$h9=3=TB;ukkHTdsHqOD5{o#*;Y_uFdd{ES+xLT-eTG6fzMm#jqV> zsp3J38q5t_6RZ==w~My=L>R2mo8!|YB#(xMgl-`eMJ&&D6+FEB*D4QNv)HAcQcD2-4w^|A?=z?RzSZfv(77SN7~hZKJ>xrK z&NddT)>p`)5ykHcn6ociRpqp)iSBre{G%Lu1!~~V#teEw z#9lN)Q?SbNSU(bbb6uZuh?%Z0QF6_@aXm5!{R%guQ!k%t;`Y}a|1Cyr^umq(J6aN~ zyXwLh&L6Iv>B_SZaiP;ZtO?l2fFWUP{hJHY(QETr%e^jXZc?Q_?@wpg6_Pag^6AYt zmHK&xP112u)oA3Yk?yhG?(q~!3s)$X7^e%CCN99oD@}L6Uq~}2*IRbSp#(Gh2vb~C) zU@_9N){k%SagCEtHs*J@*zFiPn8!i51Q^`iu#~Cpem{mka{oGdYt)ye$msR!KjK$K1jmz?SwPC6OE3b%aKP-G0CqCs{3WvXudhjQ}s^V8xA|=maOE|~* z!)vx>nWDyqA>VrsZ=Czwa`WCFCH8v)Ho5KUIG&^agh4$&<)7VLHBFWDWF@9NTB`9} z+m1M~hzeu71StxGfvv)ZcDJ0x*6piaJJX!R-;>C{N8_6`LFW=FNz>f) z>sBlV^*J76MnANCzbcwdFW|L^rt0&|oQOYHt}2ysY1&l{I5E^ogi3T&Z)B^&)tQ9A z99Ze>hdqcDn}-0li%2;&_)CjUYT1YH=V?28T)%$)=O=3$(KZo2*XhQBso{o(#j?mr zN?w!j0dU?t3Nar$zQAcDOy3bpn7SmqjNk1ae(=q>%b&TkPrMkR&Bk76EfK!b(Rp1d zhKk4bal6}9GxXujjY>39#95t4-j530MkuN}*aUeEh}gjDH6F6f{jiJ6-RJOm2UAP= zq;x%+3XWZ9p8aHPsKFw0Uv>vs198vtKYC&WWgmla5c5o$p!)wK*HOF|c?E2#$9=NYhx2Z3HkyiU-$zCWIQi1Ln)VZ>VP0mu` zmOsHtqYIWP`Il#2_3TTN_o7pq?CFJ_6nT0Mp8LTT}9A)DXsjxVrng`J*g7Bs^5+YV-H&Q z^(!C~aCo5-jgsKGHOaMFx*^{)-X?W~*&YiOQr~bFB8d5~hknS`t9)yj=1nzWtf?eh z>I^771DaWbjyg%R(cwAI2XOuu98Q|yM(^r1{9kwWA3fSx>G>&<%)R$HJ%Z0Dh-#C5 zZLjLLjr!#wbru4*<@D{|kLC4I8!O}IDc5GD zYQy%fH1ivtD3HXgNsq2t!ldX95}|%3_}5J3gGNAN#|OKSiHc8F3&PA3I%bB;5H;TH zvcsK?KA9?Q(DzoV)_mLLx0M`BBV89&CBgaZ@8YDI;LP^iinkuy5u*bhtRtL$ZP>4w zH#vpemijoky|uuaV3ik8q0&iWkJ4s!i+FDkRsZI?#5AcuG5sK*LWT>2#QU*6nr-|C zJ@x(4eGRXBJCUO3^=Vv(%(bS^&I1A8EUt-QI`mh*-fqfI;6oJagv;xPE>D-7fiN9b zLN|_c#O$Qmtef;b4cz1`0yZZ{AO}r%Tk;t0aQcoeRdspeI@MDqgK#y}hJ+?p!J2}T zc1)0x{A{vj683j7QqBltD^9MOmZnx5zC!jy3CCc}1WX)*=Z1~Q`U@$GB8nk7^RzGr zh5+_a!}pi%Le-|PpC))6x)zI3j3PEA?Qdt4n~ywn*Iy_FUn^Fk>u^7!We+|D8=4PK z3^e5AV@9(c&MZz}=c<{G;8zW2F6&`V!(I*c~Bv8#Y$G_M%!k6OlxIXVw!!))KFL z`u`BYcHK3P?64CBdNd)56pc`l6pnUUKh*!SdTj~LK7|*jJurXcr+t;5v!C@*BB_8> zUirGGC0W?AF$uf9^XlI9(b-Z)`0qFgt*MYlBbSa@KW06~dp5)cl~kdP+;OJ?@PaGIo2MFpLH zCsBe7P*L!{#&Jh&t2@xOBQeWi|CzOW-(UETR>JvDW z!Ou>U$lXb@Oi|UeI{l13TF|YG}(!IGTy5=GFdgZ_M$+H)SQEA3r8naQFy1&7zg<0KZgQ56dKt}Tk3TY%9Xg~6 znB=^004K@FV(DZ9geV`)Edhj>AO3EB9QTH?227w?%e-`_LMm0t3=Zj*c64&j*SvJ6 zA|9DOMXB_kX|)ltTe0NRcvuw_wR{72?I=-dRBL=OK{Z|nd^T}W#I*;ybSe`_-3Dq!4{F3 z-1!4IO+bIK-SdLn`L?6WMG|0WMM=&UiGuM3Ss;$290` zB8qEzpdc(CZP3)fSc_oS)P1YR?x7+E>T_88s<|3clYu{9Tz`7gK3gxeJHdJpgQG66 z8a*(ay~si+ivO7jYbt_jiAi^$K~=I6@@==n2KEE*9YPi?OHBHJ8FdZ~G~)E!J0!2} zbao!m!oK+!&%b^^>i*ZWL~Xhb+anhV$uEr}vmx2FTAv@WdZT)snDysucxMy81YgGI zx~TQlGdMQsMYR{j4_YGM6EWK|yW*{bO({%&3#FLv%z$GFH}0sBNpNHWSpp@M zh#3gW{-tHxEAYG?yE-8+Us*DUEPOb-c^~Rw{*CIIqzwNf-(LIl@3U_)#IwJFch+ThCfJ;io5`98E?{D)GZZkd`v2Su=V9!q#|d$JSDhImV00d~TUOboP`w zGcd&v+CvH~)70ix21^n-{~74?`-kdUs3Cf(X^(y2atZR z{}dt6Y#2H$=eJV(GtYM)9iQbrEwpSz-N*B07nALj9w2_%dX9~An~K^~>Wen%Cmw=! zJ*AG8)TF+ukb4+DWQcWQA5wISascLKc!3n;zW#tc>AvOh3&iE2i0B2f6A=mbvpN-e zh(}?PDuA(D;<4UvU3fAlO*JXcy;Yh$c8!e?ic)x94jIJnbkOY33Fjw`OHUlbG`FW! zW{R5COrMC=o2@c|a^&Gw8=I<^xG-J~pFUf_qa8Aa<4TI-EJ1=qsQr1N4wABx)(d&I zh!;J+MOF3A_S@MzsGka~wbau2wb?vNzxTi)9B)h)>`ct##*VZ6+>Y(~NV!)9|Otlhbo)4YVG?%?XS~nE` z^tu1}2~Zc%eJhbpvvY}>QM|OT@CQiTwWrSb*gX0P&Vv@ONO4Ad{KZt?e~<+ zH$KF9ww0zlYMT?*JPDhsV&jx&XwXdBbJr=H1a(xt0MYM55ajdFp>TIl>OnDR2L`#i zJZJq;t~6CjZwds9Z>!7z3+H}hN-w->L3opZS#y0;;rZ!Vw6HTNfRfI~Lfc&`xEOAk zsn*Jlc)YY7NS9YWNd-R3PvZ$KWdg_9@{8S}MlY^K0D)Gx+~q2yN5f+3j!tzIyR#Yw z`P$Q)#F!RJ4G&@7N+NjAZuBe zbBwGlojLN#FX+EGuwBD>yt?qFxW=X3KeivP^c{SLQ%P;un_S?GI8Aq#@N{G`izhCR z=;g?`Cr_=kY4Nh-sN)aKO7lqtm0Ey zAxy%$Kwh~TYyB#%!Yq{C0BhaCQ0({Wd}RCw)kJ%hsiYS0i;iX_^UxGI-aC7Le4GH4 zxtu4VqIrB<46!+VPgGIgNoxOKSkdl_H0KT(tOI!uQnbq?QJY)Fcdq$nZh439v|W1g z-2E$F3YPlyf;+IMvym9G1IAs3BOQd-2ZkEQfObdpS^5}`FeGn*n z&KKC%Cq6zYVFL*dcX&0cOl8dvm*7)Z&LM3YaB7>(WqBOOwzP4&8IP0NvD6C)HpgudiML#1dN%H$?`NL z?y3IDvfzCxCE{sIM-uq=s7`3~=df0hJ~cDnEttC3ojnLzrBI`Oob{`+pV_lqmyfeH zmFCSP%&(lJnuO(tw_e?0#ma!T!|LUG7zsvaD22GPjSz_XwjZI1Pr?lO6+yEDUvxz? zdXX<~>24eZ#pL#fFV8}82_>G5f+b;L#~)9SBq-2rUYAR3F|>8K?>e%<``xJzxFvxX z0TKFQ%-B8Ub6M>4{0F|r)De$cw)!%f+E-)2yxhZOy624gb0Rj6HYf55i|vaU)jrZx za2aSyb_;*)M{UY&=-%+L%y^T=#bUxyI8_$Q#jNCCT7LVhXEZ=k97Z@r6ZsvZ*B8ao zMMCnDfWaJea1+?OCidE^r-L04W8pQhX6UnaHp?sPg0Q7f(j#Szs}2}@zq&YG!WKKf zlF*bCGrG32pziRcjDu%qMht&R`o>YlMuSV5LANDpVLQ>UGNUTu3G`>W8=T?K?7|Z{ zhjLI@dL!F*=FePB}K+?XjN+t>Wt8lq{%LHYISJ%bqOulxW{o~ zREHf?9Lk9OT`^hR*$O!Q)TY2nZhY3yQl1Ek*Phinx_g44GY}Bg$-|`a{W0O&a8;(q z2O8$r7RY-8O3}&J1|o4`6(>Mol8+~w{5~)vqjQCzYdjQost(u_?2jnpi295L3KS|C zC3pB_k%Z9qs%`8#Th4Dyt7u6m%ZSOZ>1bJ(aI6iu%08|%M$Zy#M} z3v)ZzuDM*#8WH|#{pd8M+nLzN8bH3F$HG?tPRa zpKGZrKXLNarLL^{1Z9~X;JvYJTOg}F$d#{Z@=w`Bb`VvfxYA?F9Bc0>p0)St ze#WhtbC6~-og2rE3u0t(sPK3E$OQQz2@EkkRIlguvSPM+{NYmx$pl)Gu3wzIG}6KH zHhb_beTQ&o=MZH8cnY2GmdMVrDB3sufw>&0(mD&`|0cA8bV?Oe1P-T#VnmbwQ_fI$YY>%m`|^L&OxU4q0H-39&aHmpoECe zfFN|9m}73Fr;LzJ_ZcP{gq7}`iwUhiKF~QflK=3_bv9-j$aP5t1*zqW%WRAHD_k>rG`c(Qq()RNFE`C?pu2- zV#^GZLnC)mZC>q0E>Z(I8~4$xV+hSm1&F}x$^ZqbV-XN(tlfsQ{oU(8-=&_#s?&4i z)AT7asD%kL3n;Vhc3rXVdhXmz4b7SR-t0;$+wg!pf}%^hJHv9+0=e1BPL`| zTE$mRY#Hi3q$dR`&$2P>&bhMdZWkB=)`OKrs#}3TEc`q`*w3ν?Eph4y(CaCDVA z_9xG;KsVf~ozv8r*`c1)Z%@}_q-u}+DeKPi_2xY_7_UbQsy(O6lX-{d`|H93^P%16 z30;hIz1r#o@>vu&;YDaeoP-KptvYAc~gnbvLq@(;NBKqJ&kPje6Ip%E^ zmo!L4%pRv6s=pFn#zQF5p_TI!?BM4Ff2M>XM7aYddjLAi5Ow*BJ0UZM-}2@$0qig4 z4nsr8Z+9THj-D&lr^}oSFmJ}E(QA6$g*K)juC0Kfwn1;fj1jO<3fcjwe!B>fzWW>S zAmv3AadoO#foc-Rg$n=$P?pv{nO1uw_|Kn#;ESLrd{_hdy08_$zPgyX(4j|Wk217K zq90&B%psdru^ad(T9;9HdFgwmJu2eoL=LQ+hx{YckTS9dV%(o`mD|HZ#?v20>pksM z7v?`jKUd*#QpMI7gq1TY{YmaCx0vO1_&v-x=)a_vv5^w{SI4AcfD?XBz{uaoQDW%e z)Zl{0uQtOC!LJ8m^xNHcK!f)|mCJG*Kh}&liV>=clDSNvSF;d4L6{t-+Bol+aMCzi ze|hmeD396t%uVj^W{R0}ERrhcja&g~_zlb% z16Kfe!gI%h?5H;DXYE1x?$jC2y1g>rCR5+akJCfn`Q0_&c+Yg9c22{+sNKl7;YCl- zHxz_L_y>Va4zcz^XU~ygt0jo7WM&O%&lgLj_?~0O%7G~~ZeqQ#xUXczF!R6o zrI9zUZpxcpW~0(+&4A;H0ddWiP!HWOwa<#P4!%=y1nv!7L)YvR-8Hw`SLN@L4{iDy zdX6&dmy_{iP;Z@+r0(g*#FNi5NWohEZL>hmzUjxLVOO7OMzM-bSuq9@tj9RO@adq= zuIJ7@8L6D+7!lpo09o06zPTr{00&8J*y5KUHk1ac*26IiNn$p)hvf)Kq!fyp4%S`( zELgi`cy8;)Z(hPLOa3v&NqoxS_5i*2cfUIPhwC`~7kC?N0ekbRFt(BwxD(9gKkA6% zBKnO_G!{T?GH>HFimlOKeg567=+e=rj9?*2nlZ9KplPgPB+QYe^uwO3qei?`oJ<4M?Tvh03 zV*%ZUNilV!7#h5dNkd~dcWP;AFU14?0}h1J3$29SZyg~O6ggDC?3!O;yiz<}l*=Qd zc*E-0XoqhfEs)b__WQ#TdB8LEu2H78`CgrThV40im9Gf}_8K~gC+_1PU=>)`sH24VOXW)ujeX8%1@DOCd#(d2>uF1d@iMewAoOG2G94rz;?0#^3ck zanhdV;6JQz&(h zfn4+37e=-GM-Br`N&JN2bn@iZu8Ef%)YlaRl7**$0xx@~L$BWt995gZ~`(AlRzz0Da$h=3$eX*!MZ>1)kk9Ow6Ky~2qpE4Wbb)%o-`9GvDeLG7GB7yV| z@=h>ZlyIg}a*p3tuw3F|UXTff8!f;Uev&{#}C3}j*Jm%0eV~d#_p0%DKo`rZ01;d`dkbDrr4$yz}vA& z>v+sMGr55+06p2^2s1O)zV_R)$ILz*Pbs*(@IfnX zTVqnb`JS-cJ?nF;S->{(#si54(9F%cGH;tdv{?9;AaU&qS&5lbH0U$O1tMAn8J$Xy zb8*bftfgJo`{jC^jP6>x;DR~xhCq@qaV-}5b=+?D!}jz` zkhNNivj@*`yXHlU8Q|H7DX7;biXY^aS5``Yo6`w$RHnn|-k8FNdyp00-x;$m);jn` z1-gx%6HGCNg+nlM!@^I!VET>UOduDb$N(-wSpmrYkj8d7Q5;M_ndo-##Q6FNVBI14 z#pBb9#!%25f~!nSMz*r7gFDV3S-Yeh1Xbn%TzqiDS6FVszo_+( z3+`IbB;LbbRw&MhM2Fp#MdG1N#Eo+ziAY-q8%wUSV}e+;w7H=3FGQ?M!ax|)bDH3? zYxov$2SMT?UE98lJ&4DXpnb4KCni0OFZ*-$Ju9{=J3fsO&Ia7dCgL9Xt5j`XZrL(Q zX4PJ?m6wkMVHl6Wr&eTC1wC~Vq!&&J!<|)e)B-QW&=@pW_G-ToxiTCE3qQpsOS5Pj zM-u0H4J`YdxT5-_S2hK)-?U(WIZf@yR-WNC0w}__4)lV!5j_7A@t(m@?h8aQ$kBU{ z_ZD!}Y4p}Gr{!+~Fqc0HUCHVst+`6 b@TWBt?1 Welcome to the documentation of the - + [Start here with the creator's guide](xref:vpe-overview). *Be aware we're at the very beginning of writing documentation. You'll see weird content.* - \ No newline at end of file + diff --git a/VisualPinball.Unity/Documentation~/safari-pinned-tab.svg b/VisualPinball.Unity/Documentation~/safari-pinned-tab.svg deleted file mode 100644 index 426281cc1..000000000 --- a/VisualPinball.Unity/Documentation~/safari-pinned-tab.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - -Created by potrace 1.11, written by Peter Selinger 2001-2013 - - - - - diff --git a/VisualPinball.Unity/Documentation~/site.webmanifest b/VisualPinball.Unity/Documentation~/site.webmanifest index 03860619f..6de1ad0de 100644 --- a/VisualPinball.Unity/Documentation~/site.webmanifest +++ b/VisualPinball.Unity/Documentation~/site.webmanifest @@ -1,18 +1,6 @@ { "name": "Visual Pinball Engine - Documentation", "short_name": "VPE Documentation", - "icons": [ - { - "src": "/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/android-chrome-256x256.png", - "sizes": "256x256", - "type": "image/png" - } - ], "theme_color": "#ffffff", "background_color": "#ffffff", "display": "standalone" diff --git a/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl b/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl new file mode 100644 index 000000000..11a9fbd76 --- /dev/null +++ b/VisualPinball.Unity/Documentation~/template/vpe/layout/_master.tmpl @@ -0,0 +1,152 @@ +{{!Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license.}} +{{!include(/^public/.*/)}} +{{!include(favicon.ico)}} +{{!include(logo.svg)}} +{{!include(search-stopwords.json)}} + + + + + {{#redirect_url}} + + {{/redirect_url}} + {{^redirect_url}} + {{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}} + + + {{#_description}}{{/_description}} + + + + + + {{#_noindex}}{{/_noindex}} + {{#_enableSearch}}{{/_enableSearch}} + {{#_disableNewTab}}{{/_disableNewTab}} + {{#_disableTocFilter}}{{/_disableTocFilter}} + {{#docurl}}{{/docurl}} + + + + + + + + + + + + {{/redirect_url}} + + + {{^redirect_url}} + + + + + {{#_googleAnalyticsTagId}} + + + {{/_googleAnalyticsTagId}} + + +