Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Community/StrideExamples.Community.CubeClicker/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ void CreateOutlinePrimitive(Scene rootScene, PrimitiveModelType modelType, Color
var entity = game.Create3DPrimitive(modelType, options: new()
{
RenderGroup = RenderGroup.Group5,
}
);
});

entity.Transform.Position = position;
entity.Add(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Stride.Core;

namespace StrideExamples.StrideUI.Grid.Core;
namespace StrideExamples.Community.StrideUI.Grid.Core;

[DataContract]
public sealed class ClickData
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using BepuUtilities.Collections;
using Stride.Core;
using Stride.Core.Mathematics;

namespace StrideExamples.StrideUI.Grid.Core;
namespace StrideExamples.Community.StrideUI.Grid.Core;

[DataContract]
public sealed class CubeData
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using NexVYaml;
using Stride.Core.IO;

namespace StrideExamples.StrideUI.Grid.Core;
namespace StrideExamples.Community.StrideUI.Grid.Core;

public class DataSaver<TData>
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Stride.Input;

namespace StrideExamples.StrideUI.Grid.Core;
namespace StrideExamples.Community.StrideUI.Grid.Core;

public interface IClickable
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Stride.Core;
using Stride.Input;

namespace StrideExamples.StrideUI.Grid.Core;
namespace StrideExamples.Community.StrideUI.Grid.Core;

/// <summary>
/// Has to be directly [DataContract] tagged, else it won't detect it.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Stride.Core;
using Stride.Input;

namespace StrideExamples.StrideUI.Grid.Core;
namespace StrideExamples.Community.StrideUI.Grid.Core;


[DataContract]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Stride.Core;

namespace StrideExamples.StrideUI.Grid.Core;
namespace StrideExamples.Community.StrideUI.Grid.Core;

/// <summary>
/// Stride.Core.Vector isn't generated as the generator can't reach the core without being in it
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using StrideExamples.StrideUI.Grid.Core;
using StrideExamples.Community.StrideUI.Grid.Core;

namespace StrideExamples.StrideUI.Grid.Managers;
namespace StrideExamples.Community.StrideUI.Grid.Managers;

public class ClickDataManager
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
using Stride.Core.Mathematics;
using StrideExamples.StrideUI.Grid.Core;
using System.Runtime.Serialization;
using StrideExamples.Community.StrideUI.Grid.Core;

namespace StrideExamples.StrideUI.Grid.Managers;
namespace StrideExamples.Community.StrideUI.Grid.Managers;

public class CubeDataManager
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.Globalization;
using System.Text;

namespace StrideExamples.StrideUI.Grid.Managers;
namespace StrideExamples.Community.StrideUI.Grid.Managers;

public class GameManager
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
using Stride.UI;
using Stride.UI.Controls;
using Stride.UI.Events;
using Stride.UI.Panels;
using StrideExamples.StrideUI.Grid.Core;
using StrideExamples.Community.StrideUI.Grid.Core;

namespace StrideExamples.StrideUI.Grid.Managers;
namespace StrideExamples.Community.StrideUI.Grid.Managers;

public class UIManager
{
Expand Down
12 changes: 5 additions & 7 deletions Community/StrideExamples.Community.StrideUI.Grid/Program.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
using Stride.CommunityToolkit.Bepu;
using NexVYaml;
using Stride.CommunityToolkit.Bepu;
using Stride.CommunityToolkit.Engine;
using Stride.CommunityToolkit.Renderers;
using Stride.CommunityToolkit.Skyboxes;
using Stride.Engine;
using Stride.Graphics;

using NexVYaml;

using StrideExamples.StrideUI.Grid.Managers;
using StrideExamples.StrideUI.Grid.Scripts;
using Stride.CommunityToolkit.Renderers;
using StrideExamples.Community.StrideUI.Grid.Managers;
using StrideExamples.Community.StrideUI.Grid.Scripts;

using var game = new Game();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
using System.Diagnostics;
using Stride.CommunityToolkit.Bepu;
using Stride.CommunityToolkit.Engine;
using Stride.CommunityToolkit.Rendering.ProceduralModels;
using Stride.Core.Mathematics;
using Stride.Engine;
using Stride.Input;
using Stride.Rendering;
using StrideExamples.StrideUI.Grid.Managers;
using System.Diagnostics;
using StrideExamples.Community.StrideUI.Grid.Managers;

namespace StrideExamples.StrideUI.Grid.Scripts;
namespace StrideExamples.Community.StrideUI.Grid.Scripts;

public class ClickHandlerComponent : AsyncScript
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Stride.Engine;
using Stride.Physics;

namespace StrideExamples.StrideUI.Grid.Scripts;
namespace StrideExamples.Community.StrideUI.Grid.Scripts;

public class CubeGrower : AsyncScript
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Stride.Engine;
using Stride.Physics;

namespace StrideExamples.StrideUI.Grid.Scripts;
namespace StrideExamples.Community.StrideUI.Grid.Scripts;

public class CubeVanisher : AsyncScript
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using Stride.Core;
using Stride.Core.Mathematics;
using Stride.Engine;

namespace StrideExamples.Local.OcclusionTest.Components;

public class MultiRaycastVisibilityComponent : SyncScript
{
public required Game Game { get; init; }

Check warning on line 9 in Local/StrideExamples.Local.OcclusionTest/Components/MultiRaycastVisibility.cs

View workflow job for this annotation

GitHub Actions / build

'MultiRaycastVisibilityComponent.Game' hides inherited member 'ScriptComponent.Game'. Use the new keyword if hiding was intended.
public required Entity Target { get; init; }
public required CameraComponent Camera { get; init; }
public required Stride.BepuPhysics.BepuSimulation Simulation { get; init; }

public VisibilityResult LastVisibilityResult { get; private set; }

[DataMemberIgnore]
private Stride.CommunityToolkit.DebugShapes.Code.ImmediateDebugRenderSystem? _debugDraw;

public record struct VisibilityResult
{
public bool IsVisible;
public float VisibilityPercentage; // 0.0 to 1.0
public int RaysHit;
public int TotalRays;
}

public VisibilityResult CheckVisibility(Game game, Entity target, CameraComponent camera, Stride.BepuPhysics.BepuSimulation simulation)
{
_debugDraw ??= game.Services.GetService<Stride.CommunityToolkit.DebugShapes.Code.ImmediateDebugRenderSystem>();
if (_debugDraw is not null)
{
_debugDraw.Enabled = true;
_debugDraw.Visible = true;
}

var cameraPos = camera.Entity.Transform.WorldMatrix.TranslationVector;

// Get target bounding box points
var targetTransform = target.Transform;
var targetModel = target.Get<ModelComponent>();
var worldMatrix = targetTransform.WorldMatrix;
var localBoundingBox = targetModel.Model.BoundingBox;
BoundingBox.Transform(ref localBoundingBox, ref worldMatrix, out var worldBoundingBox);

var testPoints = GenerateTestPoints(worldBoundingBox);
var visibleRays = 0;

foreach (var point in testPoints)
{
var direction = point - cameraPos;

direction.Normalize();
_debugDraw?.DrawRay(cameraPos, direction*100, Color.Yellow, 0, false);

// Use Bepu's raycast method
var hit = simulation.RayCast(
cameraPos,
direction,
float.MaxValue,
out var hitInfo
);

if (hit && hitInfo.Collidable?.Entity == target)
{
visibleRays++; // Ray hit the target
}
}

var visibilityPercentage = (float)visibleRays / testPoints.Length;

return new VisibilityResult
{
IsVisible = visibilityPercentage > 0.0f,
VisibilityPercentage = visibilityPercentage,
RaysHit = visibleRays,
TotalRays = testPoints.Length
};
}

private Vector3[] GenerateTestPoints(BoundingBox boundingBox)
{
var min = boundingBox.Minimum;
var max = boundingBox.Maximum;
var center = (min + max) * 0.5f;

return
[
// 8 corners of the bounding box
new(min.X, min.Y, min.Z), // 0: min corner
new(max.X, min.Y, min.Z), // 1: +X
new(min.X, max.Y, min.Z), // 2: +Y
new(min.X, min.Y, max.Z), // 3: +Z
new(max.X, max.Y, min.Z), // 4: +XY
new(max.X, min.Y, max.Z), // 5: +XZ
new(min.X, max.Y, max.Z), // 6: +YZ
new(max.X, max.Y, max.Z), // 7: max corner

// Face centers
center, // Center
new(center.X, center.Y, min.Z), // Front face center
new(center.X, center.Y, max.Z), // Back face center
new(min.X, center.Y, center.Z), // Left face center
new(max.X, center.Y, center.Z), // Right face center
new(center.X, min.Y, center.Z), // Bottom face center
new(center.X, max.Y, center.Z), // Top face center
];
}

public override void Update()
{
LastVisibilityResult = CheckVisibility(Game, Target, Camera, Simulation);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Stride.Core.Mathematics;
using Stride.Engine;

public class MultiRaycastVisibility
{
public record struct VisibilityResult
{
public bool IsVisible;
public float VisibilityPercentage; // 0.0 to 1.0
public int RaysHit;
public int TotalRays;
}

public VisibilityResult CheckVisibility(Game game, Entity target, CameraComponent camera, Stride.BepuPhysics.BepuSimulation simulation)
{
var cameraPos = camera.Entity.Transform.WorldMatrix.TranslationVector;

// Get target bounding box points
var targetTransform = target.Transform;
var targetModel = target.Get<ModelComponent>();
var worldMatrix = targetTransform.WorldMatrix;
var localBoundingBox = targetModel.Model.BoundingBox;
BoundingBox.Transform(ref localBoundingBox, ref worldMatrix, out var worldBoundingBox);

var testPoints = GenerateTestPoints(worldBoundingBox);
var visibleRays = 0;

foreach (var point in testPoints)
{
var direction = point - cameraPos;
direction.Normalize();

// Use Bepu's raycast method
var hit = simulation.RayCast(
cameraPos,
direction,
float.MaxValue,
out var hitInfo
);

if (hit && hitInfo.Collidable?.Entity == target)
{
visibleRays++; // Ray hit the target
}
}

var visibilityPercentage = (float)visibleRays / testPoints.Length;

return new VisibilityResult
{
IsVisible = visibilityPercentage > 0.0f,
VisibilityPercentage = visibilityPercentage,
RaysHit = visibleRays,
TotalRays = testPoints.Length
};
}

private Vector3[] GenerateTestPoints(BoundingBox boundingBox)
{
var min = boundingBox.Minimum;
var max = boundingBox.Maximum;
var center = (min + max) * 0.5f;

return
[
// 8 corners of the bounding box
new(min.X, min.Y, min.Z), // 0: min corner
new(max.X, min.Y, min.Z), // 1: +X
new(min.X, max.Y, min.Z), // 2: +Y
new(min.X, min.Y, max.Z), // 3: +Z
new(max.X, max.Y, min.Z), // 4: +XY
new(max.X, min.Y, max.Z), // 5: +XZ
new(min.X, max.Y, max.Z), // 6: +YZ
new(max.X, max.Y, max.Z), // 7: max corner

// Face centers
center, // Center
new(center.X, center.Y, min.Z), // Front face center
new(center.X, center.Y, max.Z), // Back face center
new(min.X, center.Y, center.Z), // Left face center
new(max.X, center.Y, center.Z), // Right face center
new(center.X, min.Y, center.Z), // Bottom face center
new(center.X, max.Y, center.Z), // Top face center
];
}
}
18 changes: 18 additions & 0 deletions Local/StrideExamples.Local.OcclusionTest/Managers/GameManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Stride.Engine;
using Stride.Games;
using Stride.Graphics;

namespace StrideExamples.Local.OcclusionTest.Managers;

public class GameManager
{
private readonly MultiRaycastVisibility _visibility;

public UIManager UIManager { get; }

public GameManager(Scene rootScene, SpriteFont font)
{
UIManager = new UIManager(rootScene, font);
_visibility = new MultiRaycastVisibility();
}
}
Loading
Loading