Skip to content

Commit 0e75d8b

Browse files
committed
kinematic: Add support for bumpers.
1 parent e8fff4b commit 0e75d8b

File tree

11 files changed

+78
-15
lines changed

11 files changed

+78
-15
lines changed

VisualPinball.Unity/VisualPinball.Unity.Editor/VPT/Bumper/BumperColliderInspector.cs

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class BumperColliderInspector : ColliderInspector<BumperData, BumperCompo
2828
private SerializedProperty _thresholdProperty;
2929
private SerializedProperty _forceProperty;
3030
private SerializedProperty _scatterProperty;
31+
private SerializedProperty _isKinematicProperty;
3132

3233
protected override void OnEnable()
3334
{
@@ -37,6 +38,7 @@ protected override void OnEnable()
3738
_forceProperty = serializedObject.FindProperty(nameof(BumperColliderComponent.Force));
3839
_scatterProperty = serializedObject.FindProperty(nameof(BumperColliderComponent.Scatter));
3940
_hitEventProperty = serializedObject.FindProperty(nameof(BumperColliderComponent.HitEvent));
41+
_isKinematicProperty = serializedObject.FindProperty(nameof(BumperColliderComponent._isKinematic));
4042
}
4143

4244
public override void OnInspectorGUI()
@@ -47,6 +49,7 @@ public override void OnInspectorGUI()
4749

4850
BeginEditing();
4951

52+
PropertyField(_isKinematicProperty, "Movable");
5053
PropertyField(_hitEventProperty, "Has Hit Event");
5154
PropertyField(_forceProperty);
5255
PropertyField(_thresholdProperty, "Hit Threshold");

VisualPinball.Unity/VisualPinball.Unity/Extensions/MathExtensions.cs

+9
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ public static void RotationAroundAxis(this float3x3 m, float3 axis, float rSin,
5858
m.c2.z = axis.z * axis.z + rCos * (1.0f - axis.z * axis.z);
5959
}
6060

61+
public static float3 GetScale(this float4x4 m)
62+
{
63+
return new float3(
64+
math.length(new float3(m.c0.x, m.c1.x, m.c2.x)),
65+
math.length(new float3(m.c0.y, m.c1.y, m.c2.y)),
66+
math.length(new float3(m.c0.z, m.c1.z, m.c2.z))
67+
);
68+
}
69+
6170
public static Vertex3D ToVertex3D(this Vector3 vector)
6271
{
6372
return new Vertex3D(vector.x, vector.y, vector.z);

VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsEngine.cs

+15-2
Original file line numberDiff line numberDiff line change
@@ -237,9 +237,11 @@ private void Update()
237237
}
238238
var lastTransformationMatrix = _kinematicTransforms[coll.ItemId];
239239
var currTransformationMatrix = coll.TransformationMatrix;
240-
if (!lastTransformationMatrix.Equals(currTransformationMatrix)) {
241-
_updatedKinematicTransforms.Add(coll.ItemId, currTransformationMatrix);
240+
if (lastTransformationMatrix.Equals(currTransformationMatrix)) {
241+
continue;
242242
}
243+
_updatedKinematicTransforms.Add(coll.ItemId, currTransformationMatrix);
244+
_kinematicTransforms[coll.ItemId] = currTransformationMatrix;
243245
}
244246

245247
// prepare job
@@ -464,5 +466,16 @@ public ScheduledAction(ulong scheduleAt, Action action)
464466
Action = action;
465467
}
466468
}
469+
470+
public ICollider[] GetKinematicColliders(int itemId)
471+
{
472+
ref var colliderIds = ref _kinematicColliderLookups.GetValueByRef(itemId);
473+
var colliders = new ICollider[colliderIds.Length];
474+
for (var i = 0; i < colliderIds.Length; i++) {
475+
var colliderId = colliderIds[i];
476+
colliders[i] = _kinematicColliders[colliderId];
477+
}
478+
return colliders;
479+
}
467480
}
468481
}

VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsState.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree<int> octree, ref Native
101101

102102
internal ref KickerState GetKickerState(int colliderId) => ref KickerStates.GetValueByRef(Colliders.GetItemId(colliderId));
103103

104-
105104
internal bool HasDropTargetState(int colliderId) => DropTargetStates.ContainsKey(Colliders.GetItemId(colliderId));
106105

107106
internal bool HasHitTargetState(int colliderId) => HitTargetStates.ContainsKey(Colliders.GetItemId(colliderId));
@@ -110,7 +109,7 @@ public PhysicsState(ref PhysicsEnv env, ref NativeOctree<int> octree, ref Native
110109

111110
internal ref HitTargetState GetHitTargetState(int colliderId) => ref HitTargetStates.GetValueByRef(Colliders.GetItemId(colliderId));
112111

113-
internal ref BumperState GetBumperState(int colliderId) => ref BumperStates.GetValueByRef(Colliders.GetItemId(colliderId));
112+
internal ref BumperState GetBumperState(int colliderId, ref NativeColliders col) => ref BumperStates.GetValueByRef(col.GetItemId(colliderId));
114113

115114
internal ref GateState GetGateState(int colliderId) => ref GateStates.GetValueByRef(Colliders.GetItemId(colliderId));
116115

@@ -124,6 +123,10 @@ internal void Transform(int colliderId, float4x4 matrix)
124123
{
125124
switch (GetColliderType(ref KinematicColliders, colliderId))
126125
{
126+
case ColliderType.Bumper:
127+
case ColliderType.Circle:
128+
KinematicColliders.Circle(colliderId).Transform(KinematicCollidersAtIdentity.Circle(colliderId), matrix);
129+
break;
127130
case ColliderType.Point:
128131
KinematicColliders.Point(colliderId).Transform(KinematicCollidersAtIdentity.Point(colliderId), matrix);
129132
break;

VisualPinball.Unity/VisualPinball.Unity/Game/PhysicsStaticCollision.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ private static void Collide(ref NativeColliders colliders, ref BallState ball, r
8282
break;
8383

8484
case ColliderType.Bumper:
85-
ref var bumperState = ref state.GetBumperState(colliderId);
85+
ref var bumperState = ref state.GetBumperState(colliderId, ref colliders);
8686
BumperCollider.Collide(ref ball, ref state.EventQueue, ref ball.CollisionEvent, ref bumperState.RingAnimation, ref bumperState.SkirtAnimation,
8787
in collHeader, in bumperState.Static, ref state.Env.Random);
8888
break;

VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/CircleCollider.cs

+9-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ public int Id
3030

3131
public ColliderHeader Header;
3232

33-
public readonly float2 Center;
34-
public readonly float Radius;
33+
public float2 Center;
34+
public float Radius;
3535

3636
private readonly float _zHigh;
3737
private readonly float _zLow;
@@ -221,5 +221,12 @@ public void Collide(ref BallState ball, in CollisionEventData collEvent, ref Ran
221221
{
222222
BallCollider.Collide3DWall(ref ball, in Header.Material, in collEvent, in collEvent.HitNormal, ref random);
223223
}
224+
225+
public void Transform(CircleCollider circle, float4x4 matrix)
226+
{
227+
var size = matrix.GetScale();
228+
Center = math.mul(matrix, new float4(circle.Center, 0f, 1f)).xy;
229+
Radius = size.x / 2 * BumperComponent.DataMeshScale;
230+
}
224231
}
225232
}

VisualPinball.Unity/VisualPinball.Unity/Physics/Collider/ColliderReference.cs

+5
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ public void TransformToIdentity(NativeParallelHashMap<int, float4x4> itemIdToTra
9797
var matrix = itemIdToTransformationMatrix[itemId];
9898
var lookup = Lookups[colliderId];
9999
switch (lookup.Type) {
100+
case ColliderType.Bumper:
101+
case ColliderType.Circle:
102+
ref var circleCollider = ref CircleColliders.GetElementAsRef(lookup.Index);
103+
circleCollider.Transform(CircleColliders[lookup.Index], math.inverse(matrix));
104+
break;
100105
case ColliderType.Point:
101106
ref var pointCollider = ref PointColliders.GetElementAsRef(lookup.Index);
102107
pointCollider.Transform(PointColliders[lookup.Index], math.inverse(matrix));

VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperApi.cs

+7-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616

1717
using System;
18-
using System.Collections.Generic;
1918
using UnityEngine;
2019
using VisualPinball.Engine.VPT.Bumper;
2120

@@ -76,8 +75,13 @@ protected override void CreateColliders(ref ColliderReference colliders,
7675
ref ColliderReference kinematicColliders, float margin)
7776
{
7877
var height = MainComponent.PositionZ;
79-
colliders.Add(new CircleCollider(MainComponent.Position, MainComponent.Radius, height,
80-
height + MainComponent.HeightScale, GetColliderInfo(), ColliderType.Bumper));
78+
if (ColliderComponent.IsKinematic) {
79+
kinematicColliders.Add(new CircleCollider(MainComponent.Position, MainComponent.Radius, height,
80+
height + MainComponent.HeightScale, GetColliderInfo(), ColliderType.Bumper));
81+
} else {
82+
colliders.Add(new CircleCollider(MainComponent.Position, MainComponent.Radius, height,
83+
height + MainComponent.HeightScale, GetColliderInfo(), ColliderType.Bumper));
84+
}
8185
}
8286

8387
#endregion

VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperCollider.cs

-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ public static void Collide(ref BallState ball, ref NativeQueue<EventData>.Parall
2626
ref CollisionEventData collEvent, ref BumperRingAnimationState ringState, ref BumperSkirtAnimationState skirtState,
2727
in ColliderHeader collHeader, in BumperStaticState state, ref Random random)
2828
{
29-
// todo
30-
// if (!m_enabled) return;
31-
3229
var dot = math.dot(collEvent.HitNormal, ball.Velocity); // needs to be computed before Collide3DWall()!
3330
var material = collHeader.Material;
3431
BallCollider.Collide3DWall(ref ball, in material, in collEvent, in collEvent.HitNormal, ref random); // reflect ball from wall

VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperColliderComponent.cs

+13-1
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@
1616

1717
// ReSharper disable InconsistentNaming
1818

19+
using Unity.Mathematics;
1920
using UnityEngine;
2021
using VisualPinball.Engine.VPT.Bumper;
2122

2223
namespace VisualPinball.Unity
2324
{
2425
[AddComponentMenu("Visual Pinball/Collision/Bumper Collider")]
25-
public class BumperColliderComponent : ColliderComponent<BumperData, BumperComponent>
26+
public class BumperColliderComponent : ColliderComponent<BumperData, BumperComponent>, IKinematicColliderComponent
2627
{
2728
#region Data
2829

@@ -41,6 +42,17 @@ public class BumperColliderComponent : ColliderComponent<BumperData, BumperCompo
4142
[Tooltip("If set, a hit event is triggered.")]
4243
public bool HitEvent = true;
4344

45+
[Tooltip("If set, transforming this object will transform the colliders as well.")]
46+
public bool _isKinematic;
47+
48+
#endregion
49+
50+
#region IKinematicColliderComponent
51+
52+
public bool IsKinematic => _isKinematic;
53+
public int ItemId => MainComponent.gameObject.GetInstanceID();
54+
public float4x4 TransformationMatrix => MainComponent.TransformationMatrix;
55+
4456
#endregion
4557

4658
protected override IApiColliderGenerator InstantiateColliderApi(Player player, PhysicsEngine physicsEngine)

VisualPinball.Unity/VisualPinball.Unity/VPT/Bumper/BumperComponent.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ public class BumperComponent : MainRenderableComponent<BumperData>,
7777
private const string BaseMeshName = "bumper.base";
7878
private const string CapMeshName = "bumper.cap";
7979
private const string RingMeshName = "bumper.ring";
80-
private const float DataMeshScale = 100f;
80+
81+
public const float DataMeshScale = 100f;
8182

8283
public const string SocketSwitchItem = "socket_switch";
8384

@@ -146,6 +147,15 @@ public override void UpdateTransforms()
146147
t.localEulerAngles = new Vector3(0, Orientation, 0);
147148
}
148149

150+
public float4x4 TransformationMatrix {
151+
get {
152+
var scaleMatrix = float4x4.Scale(new float3(Radius * 2f, Radius * 2f, HeightScale) / DataMeshScale);
153+
var transMatrix = float4x4.Translate(new float3(Position.x, Position.y, PositionZ));
154+
var rotMatrix = float4x4.RotateZ(math.radians(Orientation));
155+
return math.mul(transMatrix, math.mul(rotMatrix, scaleMatrix));
156+
}
157+
}
158+
149159
#endregion
150160

151161
#region Conversion

0 commit comments

Comments
 (0)