129 lines
3.5 KiB
C#
129 lines
3.5 KiB
C#
using Sandbox;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
namespace VeloX;
|
|
|
|
public abstract partial class VeloXBase
|
|
{
|
|
|
|
[Property, Feature( "Powertrain" )] public Engine Engine { get; set; }
|
|
[Property, Feature( "Powertrain" )] public Clutch Clutch { get; set; }
|
|
[Property, Feature( "Powertrain" )] public Transmission Transmission { get; set; }
|
|
[Property, Feature( "Powertrain" )] public Differential Differential { get; set; }
|
|
|
|
[Property, Feature( "Powertrain" )] public List<VeloXWheel> MotorWheels { get; set; }
|
|
|
|
private GameObject powertrainGameObject;
|
|
|
|
[Button, Feature( "Powertrain" )]
|
|
internal void CreatePowertrain()
|
|
{
|
|
using var undoScope = Scene.Editor?.UndoScope( "Create Powertrain" ).WithComponentCreations().WithGameObjectCreations().Push();
|
|
if ( !powertrainGameObject.IsValid() )
|
|
{
|
|
powertrainGameObject = null;
|
|
}
|
|
powertrainGameObject ??= new GameObject( true, "Powertrain" );
|
|
|
|
if ( !Engine.IsValid() )
|
|
Engine = new GameObject( powertrainGameObject, true, "Engine" ).GetOrAddComponent<Engine>();
|
|
|
|
Engine.Controller = this;
|
|
Engine.Inertia = 0.25f;
|
|
Engine.Ignition = false;
|
|
|
|
if ( !Clutch.IsValid() )
|
|
Clutch = new GameObject( Engine.GameObject, true, "Clutch" ).GetOrAddComponent<Clutch>();
|
|
|
|
Clutch.Controller = this;
|
|
Clutch.Inertia = 0.02f;
|
|
|
|
Engine.Output = Clutch;
|
|
|
|
if ( !Transmission.IsValid() )
|
|
Transmission = new GameObject( Clutch.GameObject, true, "Transmission" ).GetOrAddComponent<Transmission>();
|
|
|
|
Transmission.Controller = this;
|
|
Transmission.Inertia = 0.01f;
|
|
|
|
Clutch.Output = Transmission;
|
|
|
|
Differential = new TreeBuilder( Transmission, MotorWheels ).Root.Diff;
|
|
|
|
Transmission.Output = Differential;
|
|
|
|
//PowertrainWheels = Differential.Components.GetAll<WheelPowertrain>( FindMode.InDescendants ).ToList();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
internal class TreeNode
|
|
{
|
|
internal TreeNode Left { get; set; }
|
|
internal TreeNode Right { get; set; }
|
|
public WheelPowertrain Item { get; set; }
|
|
public Differential Diff { get; set; }
|
|
public bool IsLeaf => Left == null && Right == null;
|
|
}
|
|
|
|
internal class TreeBuilder
|
|
{
|
|
internal TreeNode Root { get; private set; }
|
|
|
|
internal TreeBuilder( PowertrainComponent parent, List<VeloXWheel> items )
|
|
{
|
|
if ( items == null || items.Count == 0 )
|
|
throw new ArgumentException( "Items list cannot be null or empty." );
|
|
|
|
Root = BuildTree( parent, items, 0, items.Count - 1 );
|
|
}
|
|
|
|
private static TreeNode BuildTree( PowertrainComponent parent, List<VeloXWheel> items, int start, int end )
|
|
{
|
|
if ( start > end )
|
|
return null;
|
|
|
|
if ( start == end )
|
|
{
|
|
|
|
var leaf = new TreeNode() { Item = new GameObject( parent.GameObject, true, $"Wheel {items[start].GameObject.Name}" ).GetOrAddComponent<WheelPowertrain>() };
|
|
leaf.Item.Controller = parent.Controller;
|
|
leaf.Item.Wheel = items[start];
|
|
leaf.Item.Inertia = 0.01f;
|
|
var parentd = parent as Differential;
|
|
if ( (start + 1) % 2 == 0 )
|
|
{
|
|
GameTask.RunInThreadAsync( () =>
|
|
{
|
|
parentd.OutputB = leaf.Item;
|
|
} );
|
|
}
|
|
else
|
|
{
|
|
GameTask.RunInThreadAsync( () =>
|
|
{
|
|
parent.Output = leaf.Item;
|
|
} );
|
|
}
|
|
|
|
return leaf;
|
|
}
|
|
|
|
int mid = (start + end) / 2;
|
|
var diff = new GameObject( parent.GameObject, true, "Differential" ).GetOrAddComponent<Differential>();
|
|
diff.Controller = parent.Controller;
|
|
diff.Inertia = 0.1f;
|
|
var node = new TreeNode
|
|
{
|
|
Left = BuildTree( diff, items, start, mid ),
|
|
Right = BuildTree( diff, items, mid + 1, end ),
|
|
Diff = diff
|
|
};
|
|
diff.Output = node.Left.Diff;
|
|
diff.OutputB = node.Right.Diff;
|
|
return node;
|
|
}
|
|
}
|