You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.9 KiB
66 lines
1.9 KiB
2 months ago
|
#if TOOLS
|
||
|
|
||
|
|
||
|
using System.Security.Cryptography.X509Certificates;
|
||
|
|
||
|
[Tool]
|
||
|
public partial class TerrainPlugin
|
||
|
: EditorPlugin
|
||
|
{
|
||
|
public override bool _Handles(GodotObject @object)
|
||
|
=> @object is Terrain;
|
||
|
|
||
|
public override void _EnterTree()
|
||
|
{
|
||
|
// Initialization of the plugin goes here.
|
||
|
}
|
||
|
|
||
|
public override void _ExitTree()
|
||
|
{
|
||
|
// Clean-up of the plugin goes here.
|
||
|
}
|
||
|
|
||
|
Terrain _previousTerrain = null;
|
||
|
public override int _Forward3DGuiInput(Camera3D viewportCamera, InputEvent @event)
|
||
|
{
|
||
|
if (@event is not InputEventMouse) return (int)AfterGuiInput.Pass;
|
||
|
|
||
|
if (!IsInstanceValid(_previousTerrain))
|
||
|
_previousTerrain = null;
|
||
|
|
||
|
if (RayCastTerrain(viewportCamera) is var (terrain, pos, normal, shape)) {
|
||
|
if (_previousTerrain != terrain) {
|
||
|
_previousTerrain?._MouseExit();
|
||
|
terrain._MouseEnter();
|
||
|
_previousTerrain = terrain;
|
||
|
}
|
||
|
terrain._InputEvent(viewportCamera, @event, pos, normal, shape);
|
||
|
return viewportCamera.GetViewport().IsInputHandled()
|
||
|
? (int)AfterGuiInput.Stop : (int)AfterGuiInput.Pass;
|
||
|
} else {
|
||
|
_previousTerrain?._MouseExit();
|
||
|
_previousTerrain = null;
|
||
|
return (int)AfterGuiInput.Pass;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
(Terrain Terrain, Vector3 Position, Vector3 Normal, int Shape)? RayCastTerrain(Camera3D camera)
|
||
|
{
|
||
|
var viewport = camera.GetViewport();
|
||
|
var mouse = viewport.GetMousePosition();
|
||
|
if (!viewport.GetVisibleRect().HasPoint(mouse)) return null;
|
||
|
|
||
|
var from = camera.ProjectRayOrigin(mouse);
|
||
|
var to = from + camera.ProjectRayNormal(mouse) * camera.Far;
|
||
|
|
||
|
var space = camera.GetWorld3D().DirectSpaceState;
|
||
|
var query = new PhysicsRayQueryParameters3D { From = from, To = to };
|
||
|
var result = space.IntersectRay(query);
|
||
|
if (result.Count == 0) return null;
|
||
|
|
||
|
if ((GodotObject)result["collider"] is not Terrain terrain) return null;
|
||
|
return (terrain, (Vector3)result["position"], (Vector3)result["normal"], (int)result["shape"]);
|
||
|
}
|
||
|
}
|
||
|
#endif
|