1
This commit is contained in:
63
BITKit/Scripts/CSG/CSGBoxSubdivision.cs
Normal file
63
BITKit/Scripts/CSG/CSGBoxSubdivision.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using BITKit;
|
||||
|
||||
namespace BITFactory.CSG
|
||||
{
|
||||
[Tool]
|
||||
public partial class CSGBoxSubdivision : Node3D
|
||||
{
|
||||
[Export]
|
||||
private Vector3 Size
|
||||
{
|
||||
get => _size;
|
||||
set
|
||||
{
|
||||
_size = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
[Export]
|
||||
public int Level
|
||||
{
|
||||
get => _level;
|
||||
set
|
||||
{
|
||||
Rebuild();
|
||||
_level = value;
|
||||
}
|
||||
}
|
||||
private int _level;
|
||||
private Vector3 _size;
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
private void Rebuild()
|
||||
{
|
||||
foreach (var child in GetChildren())
|
||||
{
|
||||
if (child is CsgBox3D box)
|
||||
{
|
||||
box.QueueFree();
|
||||
}
|
||||
}
|
||||
|
||||
var smallBoxSize = _size / _level;
|
||||
for (var x = 0; x < _level; x++)
|
||||
{
|
||||
for (var y = 0; y < _level; y++)
|
||||
{
|
||||
var box = new CsgBox3D();
|
||||
AddChild(box);
|
||||
box.Size = smallBoxSize;
|
||||
box.Position = new Vector3(x * smallBoxSize.X, y * smallBoxSize.Y, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -53,6 +53,8 @@ public partial class FreeLookCamera : Node3D,IVirtualCamera
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (BITAppForGodot.AllowCursorExclusive) return;
|
||||
|
||||
var _rot = Quaternion.FromEuler(euler);
|
||||
var _dir = _rot * Vector3.Forward * distance;
|
||||
var newPos = Position - _dir;
|
||||
@@ -69,7 +71,7 @@ public partial class FreeLookCamera : Node3D,IVirtualCamera
|
||||
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
|
||||
if (BITAppForGodot.AllowCursorExclusive) return;
|
||||
switch (@event)
|
||||
{
|
||||
case InputEventMouseMotion mouseMotion:
|
||||
|
@@ -11,6 +11,7 @@ namespace BITKit;
|
||||
public partial class BITAppForGodot : Node
|
||||
{
|
||||
public static readonly ValidHandle AllowCursor = new();
|
||||
public static readonly ValidHandle AllowCursorExclusive = new();
|
||||
public static float DeltaTime { get; private set; }
|
||||
public static BITAppForGodot Singleton { get; private set; }
|
||||
|
||||
|
27
BITKit/Scripts/Data/SetData.cs
Normal file
27
BITKit/Scripts/Data/SetData.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
public partial class SetData : Node,IAction
|
||||
{
|
||||
[Export] private StringResource key;
|
||||
[Export] private StringResource defaultValue;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
if (defaultValue is null)
|
||||
{
|
||||
BIT4Log.Warning<SetData>($"key:{key.Value} defaultValue is null");
|
||||
}
|
||||
else
|
||||
{
|
||||
DataParser.Set(key.Value, defaultValue.Value);
|
||||
}
|
||||
}
|
||||
public void Execute(string value)
|
||||
{
|
||||
DataParser.Set(key.Value, value);
|
||||
}
|
||||
}
|
||||
}
|
@@ -28,6 +28,12 @@ public partial class Entity : Node,IEntity
|
||||
/// 所有EntityComponent
|
||||
/// </summary>
|
||||
IEntityComponent[] IEntity.Components => Components.OfType<IEntityComponent>().ToArray();
|
||||
|
||||
public void WaitForInitializationComplete()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IEntity.Id实现
|
||||
/// </summary>
|
||||
|
@@ -48,6 +48,22 @@ public partial class GodotEntitiesService : Node,IEntitiesService
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TryGetEntity(ulong id, out IEntity entity)
|
||||
{
|
||||
return _entities.TryGetValue(id, out entity);
|
||||
}
|
||||
|
||||
public IEntity GetOrAdd(ulong id, Func<ulong, IEntity> factory)
|
||||
{
|
||||
if (_entities.TryGetValue(id, out var entity))
|
||||
{
|
||||
return entity;
|
||||
}
|
||||
entity = factory(id);
|
||||
Register(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public IEntity[] Query<T>()
|
||||
{
|
||||
return _entities.Values.Where(x => x.TryGetComponent<T>(out _)).ToArray();
|
||||
|
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
using Org.BouncyCastle.Crypto.Digests;
|
||||
|
||||
namespace BITKit;
|
||||
/// <summary>
|
||||
@@ -8,6 +9,10 @@ namespace BITKit;
|
||||
/// </summary>
|
||||
public static partial class MathNode
|
||||
{
|
||||
public static T Cast<T>(this Node node) where T : Node
|
||||
{
|
||||
return (T)node.GetNode(new NodePath(node.Name));
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取Node下所有的子Node节点
|
||||
/// </summary>
|
||||
@@ -17,6 +22,8 @@ public static partial class MathNode
|
||||
{
|
||||
List<Node> nodes = new() { self };
|
||||
For(self);
|
||||
return nodes.Distinct();
|
||||
|
||||
void For(Node node)
|
||||
{
|
||||
foreach (var x in node.GetChildren())
|
||||
@@ -25,9 +32,27 @@ public static partial class MathNode
|
||||
nodes.Add(x);
|
||||
}
|
||||
}
|
||||
return nodes.Distinct();
|
||||
}
|
||||
|
||||
public static IEnumerable<Node> GetNodesInParent(Node self)
|
||||
{
|
||||
var nodes = new List<Node>() { self };
|
||||
var parent = self.GetParent();
|
||||
while (parent is not null)
|
||||
{
|
||||
nodes.Add(parent);
|
||||
parent = parent.GetParent();
|
||||
}
|
||||
return nodes.Distinct();
|
||||
}
|
||||
public static bool TryGetNodeInParent<T>(Node self, out T node)
|
||||
{
|
||||
node = default;
|
||||
var nodes = GetNodesInParent(self);
|
||||
if (nodes.FirstOrDefault(x => x is T) is not T t) return false;
|
||||
node = t;
|
||||
return true;
|
||||
}
|
||||
public static void ClearChild(Node self)
|
||||
{
|
||||
foreach (var x in self.GetChildren())
|
||||
|
10
BITKit/Scripts/Resource/ResourceT.cs
Normal file
10
BITKit/Scripts/Resource/ResourceT.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
public partial class BITResource<T> : Resource
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -8,4 +8,8 @@ public partial class StringResource : Resource
|
||||
[Export]
|
||||
private string value { get; set; }
|
||||
public string Value => value;
|
||||
public static implicit operator string(StringResource resource)
|
||||
{
|
||||
return resource.Value;
|
||||
}
|
||||
}
|
||||
|
122
BITKit/Scripts/Selector/CameraSelector.cs
Normal file
122
BITKit/Scripts/Selector/CameraSelector.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using BITKit.Selection;
|
||||
|
||||
namespace BITKit
|
||||
{
|
||||
public partial class CameraSelector : EntityBehaviour,ISelector
|
||||
{
|
||||
[Export] private Node3D node3D;
|
||||
[Export] private Control control;
|
||||
[Export] private float distance;
|
||||
|
||||
private ISelectable _currentSelectable;
|
||||
|
||||
private readonly ValidHandle _isEnabled = new();
|
||||
public override void _EnterTree()
|
||||
{
|
||||
base._EnterTree();
|
||||
DI.Register<ISelector>(this);
|
||||
}
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
if (control is not null)
|
||||
{
|
||||
control.MouseEntered += () => _isEnabled.RemoveDisableElements(control);
|
||||
control.MouseExited += () => _isEnabled.AddDisableElements(control);
|
||||
}
|
||||
_isEnabled.AddElement(this);
|
||||
}
|
||||
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
base._Input(@event);
|
||||
switch (@event)
|
||||
{
|
||||
case InputEventMouseButton { Pressed: true}:
|
||||
if (_currentSelectable is not null)
|
||||
{
|
||||
_currentSelectable.SetSelectionState(SelectionState.Selected);
|
||||
OnSelected?.Invoke(_currentSelectable);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
base._Process(delta);
|
||||
if (!_isEnabled)
|
||||
{
|
||||
if (_currentSelectable is not null)
|
||||
{
|
||||
_currentSelectable.SetSelectionState(SelectionState.None);
|
||||
OnNone?.Invoke(_currentSelectable);
|
||||
_currentSelectable = null;
|
||||
}
|
||||
}
|
||||
|
||||
var mousePosition = GetViewport().GetMousePosition();
|
||||
var origin = CameraService.Singleton.ProjectRayOrigin(mousePosition);
|
||||
var normal = CameraService.Singleton.ProjectRayNormal(mousePosition);
|
||||
var end = origin + normal * distance;
|
||||
var query = PhysicsRayQueryParameters3D.Create(origin, end);
|
||||
query.CollideWithAreas = true;
|
||||
|
||||
var spaceState =node3D.GetWorld3D().DirectSpaceState;
|
||||
var result = spaceState.IntersectRay(query);
|
||||
|
||||
ISelectable currentSelected=null;
|
||||
if (result.TryGetValue("collider", out var collider))
|
||||
{
|
||||
var node = (Node3D)collider;
|
||||
//var pos = (Vector3)result["position"];
|
||||
|
||||
MathNode.TryGetNodeInParent<ISelectable>(node, out currentSelected);
|
||||
}
|
||||
|
||||
//BIT4Log.Log($"currentSelected:{currentSelected}");
|
||||
|
||||
switch (currentSelected,_currentSelectable)
|
||||
{
|
||||
case (not null,not null) when currentSelected != _currentSelectable:
|
||||
OnNone?.Invoke(_currentSelectable);
|
||||
_currentSelectable.SetSelectionState(SelectionState.None);
|
||||
_currentSelectable = currentSelected;
|
||||
_currentSelectable.SetSelectionState(SelectionState.Hover);
|
||||
OnHover?.Invoke(_currentSelectable);
|
||||
break;
|
||||
case (null,null): break;
|
||||
case (null,not null):
|
||||
_currentSelectable.SetSelectionState(SelectionState.None);
|
||||
OnNone?.Invoke(_currentSelectable);
|
||||
_currentSelectable = null;
|
||||
break;
|
||||
case (not null,null):
|
||||
_currentSelectable = currentSelected;
|
||||
_currentSelectable.SetSelectionState(SelectionState.Hover);
|
||||
OnHover?.Invoke(_currentSelectable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetCurrentSelectable(out ISelectable selectable)
|
||||
{
|
||||
selectable = _currentSelectable;
|
||||
return selectable is not null;
|
||||
}
|
||||
|
||||
public event Action<ISelectable> OnNone;
|
||||
public event Action<ISelectable> OnHover;
|
||||
public event Action<ISelectable> OnActive;
|
||||
public event Action<ISelectable> OnInactive;
|
||||
public event Action<ISelectable> OnFocus;
|
||||
public event Action<ISelectable> OnSelected;
|
||||
public event Action<ISelectable> OnEnabled;
|
||||
public event Action<ISelectable> OnChecked;
|
||||
public event Action<ISelectable> OnRoot;
|
||||
}
|
||||
|
||||
}
|
22
BITKit/Scripts/Selector/Selectable.cs
Normal file
22
BITKit/Scripts/Selector/Selectable.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using BITKit;
|
||||
|
||||
namespace BITKit.Selection
|
||||
{
|
||||
public partial class Selectable : EntityBehaviour,ISelectable
|
||||
{
|
||||
public void SetSelectionState(SelectionState state)
|
||||
{
|
||||
}
|
||||
public event Action OnNone;
|
||||
public event Action OnHover;
|
||||
public event Action OnActive;
|
||||
public event Action OnInactive;
|
||||
public event Action OnFocus;
|
||||
public event Action OnSelected;
|
||||
public event Action OnEnabled;
|
||||
public event Action OnChecked;
|
||||
public event Action OnRoot;
|
||||
}
|
||||
}
|
@@ -5,11 +5,14 @@ using System.Linq;
|
||||
|
||||
namespace BITKit.StateMachine
|
||||
{
|
||||
public abstract partial class StateMachineNode<T> : Node ,IStateMachine<T> where T : class, IState
|
||||
|
||||
public abstract partial class StateMachineNode<T> : Node ,IStateMachine<T> where T : class, IState
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public T CurrentState { get; set; }
|
||||
public event Action<T, T> OnStateChanged;
|
||||
public event Action<T> OnStateRegistered;
|
||||
public event Action<T> OnStateUnRegistered;
|
||||
public IDictionary<Type, T> StateDictionary { get; } = new Dictionary<Type, T>();
|
||||
public void Initialize()
|
||||
{
|
||||
|
56
BITKit/Scripts/UX/UXBasedModelViewer.cs
Normal file
56
BITKit/Scripts/UX/UXBasedModelViewer.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
namespace BITKit.UX
|
||||
{
|
||||
public partial class UXBasedModelViewer : Control
|
||||
{
|
||||
[Export] private float delta = 0.1f;
|
||||
[Export] private Node3D model;
|
||||
|
||||
private readonly ValidHandle _isEnabled = new();
|
||||
|
||||
private Vector2 _velocity;
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
MouseEntered += () => _isEnabled.RemoveDisableElements(this);
|
||||
MouseExited += () => _isEnabled.AddDisableElements(this);
|
||||
_isEnabled.SetDisableElements(1,false);
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
base._Process(delta);
|
||||
_isEnabled.SetDisableElements(1,!Visible);
|
||||
if (_velocity == default) return;
|
||||
|
||||
var rotate = _velocity * this.delta * (float)delta;
|
||||
|
||||
model.RotateX(Mathf.DegToRad(rotate.Y));
|
||||
model.RotateY(Mathf.DegToRad(rotate.X));
|
||||
|
||||
_velocity = Vector2.Zero;
|
||||
|
||||
|
||||
}
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
base._Input(@event);
|
||||
switch (@event)
|
||||
{
|
||||
case InputEventMouseButton button:
|
||||
_isEnabled.SetElements(this,button.Pressed);
|
||||
break;
|
||||
case InputEventMouseMotion motion when _isEnabled:
|
||||
_velocity += motion.Relative;
|
||||
break;
|
||||
}
|
||||
}
|
||||
public void Reset()
|
||||
{
|
||||
model.RotationDegrees = Vector3.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
19
BITKit/Scripts/UX/UXControl.cs
Normal file
19
BITKit/Scripts/UX/UXControl.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BITKit.UX
|
||||
{
|
||||
public partial class UXControl : Control
|
||||
{
|
||||
private readonly Queue<ImageTexture> _imageTextureQueue = new();
|
||||
public void DrawTextureRect(ImageTexture texture)=>_imageTextureQueue.Enqueue(texture);
|
||||
public override void _Draw()
|
||||
{
|
||||
while (_imageTextureQueue.TryDequeue(out var texture))
|
||||
{
|
||||
DrawTextureRect(texture, GetRect(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user