macrosoft3dpinball/godot/scenes/table.tscn
m3ultra 2ca67bb28b Add Godot 4.7 physics testbed: Box3D/Jolt/GodotPhysics A/B pinball table
Playable table (hinge-motor flippers, plunger, bumper, drain) plus a headless
probe harness that measured, per engine: tunneling of a fast ball through a
1 cm wall with CCD off/on, and hinge-motor drive. Findings in godot/README.md:
Box3D never tunnels even with CCD off, but its hinge motor sign is inverted
vs Jolt/GodotPhysics, and Jolt blows through angular limits that Box3D holds.
Ships a from-source macOS arm64 libgodot-box3d.dylib (upstream has no
releases). Also gitignore the remaining Microsoft media at repo root.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 05:33:07 +10:00

263 lines
9.1 KiB
Plaintext

[gd_scene load_steps=28 format=3]
[ext_resource type="Script" path="res://scenes/table.gd" id="1"]
[sub_resource type="BoxShape3D" id="floor_shape"]
size = Vector3(0.54, 0.02, 1.04)
[sub_resource type="BoxMesh" id="floor_mesh"]
size = Vector3(0.54, 0.02, 1.04)
[sub_resource type="StandardMaterial3D" id="mat_floor"]
albedo_color = Color(0.13, 0.28, 0.16, 1)
[sub_resource type="BoxShape3D" id="wall_long_shape"]
size = Vector3(0.02, 0.06, 1.04)
[sub_resource type="BoxMesh" id="wall_long_mesh"]
size = Vector3(0.02, 0.06, 1.04)
[sub_resource type="BoxShape3D" id="wall_short_shape"]
size = Vector3(0.54, 0.06, 0.02)
[sub_resource type="BoxMesh" id="wall_short_mesh"]
size = Vector3(0.54, 0.06, 0.02)
[sub_resource type="StandardMaterial3D" id="mat_wall"]
albedo_color = Color(0.45, 0.42, 0.38, 1)
[sub_resource type="BoxShape3D" id="lane_shape"]
size = Vector3(0.01, 0.06, 0.79)
[sub_resource type="BoxMesh" id="lane_mesh"]
size = Vector3(0.01, 0.06, 0.79)
[sub_resource type="BoxShape3D" id="guide_l_shape"]
size = Vector3(0.16, 0.06, 0.01)
[sub_resource type="BoxMesh" id="guide_l_mesh"]
size = Vector3(0.16, 0.06, 0.01)
[sub_resource type="BoxShape3D" id="guide_r_shape"]
size = Vector3(0.13, 0.06, 0.01)
[sub_resource type="BoxMesh" id="guide_r_mesh"]
size = Vector3(0.13, 0.06, 0.01)
[sub_resource type="BoxShape3D" id="flipper_shape"]
size = Vector3(0.1, 0.03, 0.022)
[sub_resource type="BoxMesh" id="flipper_mesh"]
size = Vector3(0.1, 0.03, 0.022)
[sub_resource type="StandardMaterial3D" id="mat_flipper"]
albedo_color = Color(0.85, 0.15, 0.12, 1)
[sub_resource type="SphereShape3D" id="ball_shape"]
radius = 0.0135
[sub_resource type="SphereMesh" id="ball_mesh"]
radius = 0.0135
height = 0.027
[sub_resource type="StandardMaterial3D" id="mat_ball"]
albedo_color = Color(0.75, 0.75, 0.8, 1)
metallic = 0.9
roughness = 0.25
[sub_resource type="PhysicsMaterial" id="ball_phys"]
friction = 0.25
bounce = 0.3
[sub_resource type="CylinderShape3D" id="bumper_shape"]
height = 0.05
radius = 0.035
[sub_resource type="CylinderMesh" id="bumper_mesh"]
top_radius = 0.035
bottom_radius = 0.035
height = 0.05
[sub_resource type="StandardMaterial3D" id="mat_bumper"]
albedo_color = Color(0.95, 0.55, 0.1, 1)
[sub_resource type="CylinderShape3D" id="bumper_area_shape"]
height = 0.08
radius = 0.055
[sub_resource type="BoxShape3D" id="drain_shape"]
size = Vector3(0.2, 0.06, 0.04)
[node name="Table" type="Node3D"]
script = ExtResource("1")
[node name="Playfield" type="StaticBody3D" parent="."]
[node name="FloorShape" type="CollisionShape3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.01, 0)
shape = SubResource("floor_shape")
[node name="FloorMesh" type="MeshInstance3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.01, 0)
mesh = SubResource("floor_mesh")
surface_material_override/0 = SubResource("mat_floor")
[node name="WallLeftShape" type="CollisionShape3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.26, 0.03, 0)
shape = SubResource("wall_long_shape")
[node name="WallLeftMesh" type="MeshInstance3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.26, 0.03, 0)
mesh = SubResource("wall_long_mesh")
surface_material_override/0 = SubResource("mat_wall")
[node name="WallRightShape" type="CollisionShape3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.26, 0.03, 0)
shape = SubResource("wall_long_shape")
[node name="WallRightMesh" type="MeshInstance3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.26, 0.03, 0)
mesh = SubResource("wall_long_mesh")
surface_material_override/0 = SubResource("mat_wall")
[node name="WallFarShape" type="CollisionShape3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.03, -0.51)
shape = SubResource("wall_short_shape")
[node name="WallFarMesh" type="MeshInstance3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.03, -0.51)
mesh = SubResource("wall_short_mesh")
surface_material_override/0 = SubResource("mat_wall")
[node name="WallNearShape" type="CollisionShape3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.03, 0.51)
shape = SubResource("wall_short_shape")
[node name="WallNearMesh" type="MeshInstance3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.03, 0.51)
mesh = SubResource("wall_short_mesh")
surface_material_override/0 = SubResource("mat_wall")
[node name="LaneWallShape" type="CollisionShape3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.21, 0.03, 0.075)
shape = SubResource("lane_shape")
[node name="LaneWallMesh" type="MeshInstance3D" parent="Playfield"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.21, 0.03, 0.075)
mesh = SubResource("lane_mesh")
surface_material_override/0 = SubResource("mat_wall")
[node name="GuideLeftShape" type="CollisionShape3D" parent="Playfield"]
transform = Transform3D(0.768, 0, -0.64, 0, 1, 0, 0.64, 0, 0.768, -0.19, 0.03, 0.35)
shape = SubResource("guide_l_shape")
[node name="GuideLeftMesh" type="MeshInstance3D" parent="Playfield"]
transform = Transform3D(0.768, 0, -0.64, 0, 1, 0, 0.64, 0, 0.768, -0.19, 0.03, 0.35)
mesh = SubResource("guide_l_mesh")
surface_material_override/0 = SubResource("mat_wall")
[node name="GuideRightShape" type="CollisionShape3D" parent="Playfield"]
transform = Transform3D(-0.768, 0, -0.64, 0, 1, 0, 0.64, 0, -0.768, 0.167, 0.03, 0.35)
shape = SubResource("guide_r_shape")
[node name="GuideRightMesh" type="MeshInstance3D" parent="Playfield"]
transform = Transform3D(-0.768, 0, -0.64, 0, 1, 0, 0.64, 0, -0.768, 0.167, 0.03, 0.35)
mesh = SubResource("guide_r_mesh")
surface_material_override/0 = SubResource("mat_wall")
[node name="LeftFlipper" type="RigidBody3D" parent="."]
transform = Transform3D(0.906, 0, -0.423, 0, 1, 0, 0.423, 0, 0.906, -0.115, 0.02, 0.42)
mass = 0.15
continuous_cd = true
can_sleep = false
[node name="Shape" type="CollisionShape3D" parent="LeftFlipper"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.05, 0, 0)
shape = SubResource("flipper_shape")
[node name="Mesh" type="MeshInstance3D" parent="LeftFlipper"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.05, 0, 0)
mesh = SubResource("flipper_mesh")
surface_material_override/0 = SubResource("mat_flipper")
[node name="RightFlipper" type="RigidBody3D" parent="."]
transform = Transform3D(0.906, 0, 0.423, 0, 1, 0, -0.423, 0, 0.906, 0.115, 0.02, 0.42)
mass = 0.15
continuous_cd = true
can_sleep = false
[node name="Shape" type="CollisionShape3D" parent="RightFlipper"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.05, 0, 0)
shape = SubResource("flipper_shape")
[node name="Mesh" type="MeshInstance3D" parent="RightFlipper"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.05, 0, 0)
mesh = SubResource("flipper_mesh")
surface_material_override/0 = SubResource("mat_flipper")
[node name="LeftFlipperJoint" type="HingeJoint3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, -0.115, 0.02, 0.42)
node_a = NodePath("../Playfield")
node_b = NodePath("../LeftFlipper")
angular_limit/enable = true
angular_limit/upper = 0.873
angular_limit/lower = -0.087
motor/enable = true
motor/target_velocity = -8.0
motor/max_impulse = 0.6
[node name="RightFlipperJoint" type="HingeJoint3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0.115, 0.02, 0.42)
node_a = NodePath("../Playfield")
node_b = NodePath("../RightFlipper")
angular_limit/enable = true
angular_limit/upper = 0.087
angular_limit/lower = -0.873
motor/enable = true
motor/target_velocity = 8.0
motor/max_impulse = 0.6
[node name="Ball" type="RigidBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.2325, 0.0135, 0.44)
mass = 0.08
physics_material_override = SubResource("ball_phys")
continuous_cd = true
can_sleep = false
[node name="Shape" type="CollisionShape3D" parent="Ball"]
shape = SubResource("ball_shape")
[node name="Mesh" type="MeshInstance3D" parent="Ball"]
mesh = SubResource("ball_mesh")
surface_material_override/0 = SubResource("mat_ball")
[node name="Bumper" type="StaticBody3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, -0.1)
[node name="Shape" type="CollisionShape3D" parent="Bumper"]
shape = SubResource("bumper_shape")
[node name="Mesh" type="MeshInstance3D" parent="Bumper"]
mesh = SubResource("bumper_mesh")
surface_material_override/0 = SubResource("mat_bumper")
[node name="BumperArea" type="Area3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.025, -0.1)
[node name="Shape" type="CollisionShape3D" parent="BumperArea"]
shape = SubResource("bumper_area_shape")
[node name="Drain" type="Area3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.03, 0.485)
[node name="Shape" type="CollisionShape3D" parent="Drain"]
shape = SubResource("drain_shape")
[node name="Camera3D" type="Camera3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.417, 0.909, 0, -0.909, 0.417, 0, 1.2, 0.55)
fov = 30.0
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.5, 0.866, 0, -0.866, 0.5, 0, 1, 0)
shadow_enabled = true