train on bogie on track

This commit is contained in:
ktyl 2022-08-18 00:42:04 +01:00 committed by Cat Flynn
parent fb9c9d631d
commit b93511d12f
5 changed files with 107 additions and 17 deletions

View File

@ -7,6 +7,7 @@
[node name="Main" type="Node2D"] [node name="Main" type="Node2D"]
[node name="Train" parent="." instance=ExtResource( 1 )] [node name="Train" parent="." instance=ExtResource( 1 )]
_speed = 5.0
_railwayPath = NodePath("../Railway") _railwayPath = NodePath("../Railway")
[node name="DirectionalLight" type="DirectionalLight" parent="."] [node name="DirectionalLight" type="DirectionalLight" parent="."]

View File

@ -5,5 +5,6 @@
[node name="Train" type="Spatial"] [node name="Train" type="Spatial"]
script = ExtResource( 1 ) script = ExtResource( 1 )
_carPath = NodePath("Train Car")
[node name="Train Car" parent="." instance=ExtResource( 2 )] [node name="Train Car" parent="." instance=ExtResource( 2 )]

View File

@ -5,6 +5,7 @@
[node name="Train Car" type="Spatial"] [node name="Train Car" type="Spatial"]
script = ExtResource( 1 ) script = ExtResource( 1 )
Wheelbase = 5.0
_boxNode = NodePath("CSGBox") _boxNode = NodePath("CSGBox")
_bogiePaths = [ NodePath("Bogie"), NodePath("Bogie2") ] _bogiePaths = [ NodePath("Bogie"), NodePath("Bogie2") ]
@ -15,7 +16,7 @@ height = 1.0
depth = 8.0 depth = 8.0
[node name="Bogie" parent="." instance=ExtResource( 2 )] [node name="Bogie" parent="." instance=ExtResource( 2 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2 ) transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2.5 )
[node name="Bogie2" parent="." instance=ExtResource( 2 )] [node name="Bogie2" parent="." instance=ExtResource( 2 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2 ) transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2.5 )

View File

@ -1,5 +1,6 @@
using Godot; using Godot;
using System; using System;
using System.Collections.Generic;
public class Train : Spatial public class Train : Spatial
{ {
@ -10,17 +11,48 @@ public class Train : Spatial
private NodePath _railwayPath; private NodePath _railwayPath;
private Railway _railway; private Railway _railway;
private readonly PathFollow _pathFollow = new PathFollow
{
RotationMode = PathFollow.RotationModeEnum.Oriented
};
private float _distance = 0; private float _distance = 0;
[Export]
private NodePath _carPath;
private TrainCar _car;
private Spatial[] _bogies;
private readonly Dictionary<Spatial, PathFollow> _bogiePathFollows = new Dictionary<Spatial, PathFollow>();
private ImmediateGeometry _imgui;
// Called when the node enters the scene tree for the first time. // Called when the node enters the scene tree for the first time.
public override void _Ready() public override void _Ready()
{ {
_railway = GetNode<Railway>(_railwayPath) as Railway; _imgui = new ImmediateGeometry();
_railway.AddPathFollower(_pathFollow); var m = new SpatialMaterial();
m.VertexColorUseAsAlbedo = true;
m.FlagsUnshaded = true;
_imgui.MaterialOverride = m;
AddChild(_imgui);
_railway = GetNode<Railway>(_railwayPath);
_car = GetNode<TrainCar>(_carPath);
_bogies = new Spatial[_car.Bogies.Length];
for (int i = 0; i < _bogies.Length; i++)
{
var b = _car.Bogies[i];
_bogies[i] = b;
_bogiePathFollows[b] = new PathFollow
{
RotationMode = PathFollow.RotationModeEnum.Oriented
};
_railway.AddPathFollower(_bogiePathFollows[b]);
// detach the bogies from the car as we need to set the bogie
// positions in order to calculate the car position and it will
// get confusing if they're in a parent/child relationship,
// so make them all siblings
_car.RemoveChild(b);
this.AddChild(b);
}
} }
// Called every frame. 'delta' is the elapsed time since the previous frame. // Called every frame. 'delta' is the elapsed time since the previous frame.
@ -28,6 +60,12 @@ public class Train : Spatial
{ {
var length = _railway.Curve.GetBakedLength(); var length = _railway.Curve.GetBakedLength();
// first determine which is the front bogie. this is dependent
// on the direction of travel.
int travelDir = (int)(_distance / length) == 0 ? -1 : 1;
DrawTravelDirectionIndicator(travelDir);
// keep track of total distance // keep track of total distance
_distance += delta * _speed; _distance += delta * _speed;
// wrap at 2x total distance // wrap at 2x total distance
@ -35,9 +73,40 @@ public class Train : Spatial
var distance = PingPong(_distance, length); var distance = PingPong(_distance, length);
_pathFollow.Offset = distance; // get the position of the first bogie on the track
Translation = _pathFollow.Translation; var b = _bogies[0];
Rotation = _pathFollow.Rotation; var pathFollow = _bogiePathFollows[b];
pathFollow.Offset = distance;
b.Translation = pathFollow.Translation;
b.Rotation = pathFollow.Rotation;
// now we want to position the car over the first bogie
GD.Print(_car.Wheelbase);
_car.Translation = b.Translation;
_car.Rotation = b.Rotation;
// TODO: this rotation quat needs to position the other
// bogie over the curve
_car.Translation += _car.Transform.basis
.RotationQuat()
.Xform(Vector3.Back) * _car.Wheelbase * 0.5f;
}
private void DrawTravelDirectionIndicator(int travelDir)
{
_imgui.Clear();
_imgui.Begin(Mesh.PrimitiveType.LineStrip);
_imgui.SetColor(new Color(1, 0, 0));
var c = _car.Translation + Vector3.Up * 2;
_imgui.AddVertex(c);
var d = travelDir;
var l = 5;
var e = c + _car.Transform.basis
.RotationQuat()
.Xform(Vector3.Forward) * d * l;
_imgui.AddVertex(e);
_imgui.End();
} }
// poor mans branching ping pong // poor mans branching ping pong

View File

@ -13,21 +13,37 @@ public class TrainCar : Spatial
private NodePath[] _bogiePaths; private NodePath[] _bogiePaths;
[Export] [Export]
private float Wheelbase public float Wheelbase
{ {
get => _wheelbase; get => _wheelbase;
set set
{ {
_wheelbase = value; _wheelbase = value;
if (Engine.EditorHint)
{ // don't set the wheelbase except from the editor
if (!Engine.EditorHint) return;
SetBogeyPositions(); SetBogeyPositions();
} }
} }
}
private float _wheelbase; private float _wheelbase;
private readonly Spatial[] _bogies = new Spatial[2]; public Spatial[] Bogies
{
get
{
if (_bogies == null)
{
_bogies = new Spatial[2];
for (int i = 0; i < _bogiePaths.Length; i++)
{
_bogies[i] = GetNode<Spatial>(_bogiePaths[i]);
}
}
return _bogies;
}
}
private Spatial[] _bogies = null;
private CSGBox _box; private CSGBox _box;
private CSGBox Box private CSGBox Box
@ -42,6 +58,8 @@ public class TrainCar : Spatial
} }
} }
public Railway Railway { get; set; }
public override void _Ready() public override void _Ready()
{ {