Skip to content

Commit

Permalink
Merge pull request #27 from thiagomvas/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
thiagomvas authored Jun 18, 2024
2 parents 393cfce + 8189013 commit 1d2c3ae
Show file tree
Hide file tree
Showing 34 changed files with 771 additions and 70 deletions.
2 changes: 1 addition & 1 deletion Basalt.Core/Basalt.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>1.8.1</Version>
<Version>1.9.0</Version>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageIcon>BasaltLogoBg.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
Expand Down
2 changes: 1 addition & 1 deletion Basalt.Raylib/Basalt.Raylib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>1.8.1</Version>
<Version>1.9.0</Version>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<PackageIcon>BasaltLogoBg.png</PackageIcon>
<PackageReadmeFile>README.md</PackageReadmeFile>
Expand Down
45 changes: 45 additions & 0 deletions Basalt.Raylib/Components/FirstPersonCameraController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Basalt.Common.Entities;
using Basalt.Math;
using System.Numerics;
using static Raylib_cs.Raylib;

namespace Basalt.Raylib.Components
{
/// <summary>
/// Represents a first-person camera controller for Raylib.
/// </summary>
public class FirstPersonCameraController : RayCameraController
{
/// <summary>
/// The sensitivity of the camera controller.
/// </summary>
public float Sensitivity = 0.1f;

/// <summary>
/// Initializes a new instance of the <see cref="FirstPersonCameraController"/> class.
/// </summary>
/// <param name="entity">The entity associated with the camera controller.</param>
public FirstPersonCameraController(Entity entity) : base(entity)
{
}

public override void OnUpdate()
{
if (!Enabled)
return;

Vector3 rotation = new(GetMouseDelta().X * Sensitivity, // Rotation: yaw
GetMouseDelta().Y * Sensitivity, // Rotation: pitch
0.0f); // Rotation: roll

// Update the camera in raylib

camera.Position = Entity.Transform.Position;
camera.Target = camera.Position + Entity.Transform.Forward;

UpdateCameraPro(ref camera, Vector3.Zero, rotation, 0);

Entity.Transform.Rotation = BasaltMath.LookAtRotation(camera.Position, camera.Target, camera.Up);
}
}
}
2 changes: 1 addition & 1 deletion Basalt.Raylib/Components/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
using Basalt.Common.Utils;
using Basalt.Raylib.Graphics;
using Raylib_cs;
using static Raylib_cs.Raylib;
using System.Numerics;
using static Raylib_cs.Raylib;

namespace Basalt.Raylib.Components
{
Expand Down
2 changes: 1 addition & 1 deletion Basalt.Raylib/Components/ModelRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public override unsafe void OnRender()
cube = ResourceCache.Instance.GetModel(ModelCacheKey)!.Value;
else
{
throw new InvalidResourceKeyException(nameof(ModelCacheKey));
throw new InvalidResourceKeyException(nameof(ModelCacheKey), ModelCacheKey);
}
init = true;
}
Expand Down
39 changes: 39 additions & 0 deletions Basalt.Raylib/Components/RayCameraController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Basalt.Common.Components;
using Basalt.Common.Entities;
using Raylib_cs;
using System.Numerics;

namespace Basalt.Raylib.Components
{
/// <summary>
/// Represents a camera controller for Raylib using Camera3D.
/// </summary>
public class RayCameraController : CameraControllerBase<Camera3D>
{
/// <summary>
/// Initializes a new instance of the <see cref="RayCameraController"/> class.
/// </summary>
/// <param name="entity">The entity associated with the camera controller.</param>
public RayCameraController(Entity entity) : base(entity)
{
Camera = new Camera3D
{
Position = Entity.Transform.Position,
Target = Entity.Transform.Position + Entity.Transform.Forward,
Up = new Vector3(0f, 1f, 0f),
FovY = 60f,
Projection = CameraProjection.Perspective
};

// Set the camera as the active camera in raylib
Raylib_cs.Raylib.UpdateCamera(ref camera, CameraMode.FirstPerson);
}

protected Camera3D camera;

/// <summary>
/// Gets or sets the camera.
/// </summary>
public override Camera3D Camera { get => camera; set => camera = value; }
}
}
55 changes: 55 additions & 0 deletions Basalt.Raylib/Components/RaylibParticleSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Basalt.Common.Components;
using Basalt.Common.Entities;
using Basalt.Common.Exceptions;
using Basalt.Common.Utils;
using Basalt.Raylib.Graphics;
using Raylib_cs;
using System.Numerics;

namespace Basalt.Raylib.Components
{
/// <summary>
/// A particle system that renders particles using Raylib.
/// </summary>
public class RaylibParticleSystem : BaseParticleSystem
{
private string _modelCacheKey = "sphere";
/// <summary>
/// The <see cref="ResourceCache"/> cache key for the model to use for rendering particles.
/// </summary>
public string ModelCacheKey
{
get => _modelCacheKey;
set
{
_modelCacheKey = value;
init = false;
}
}
bool init = false;
Model model;
public RaylibParticleSystem(Entity entity) : base(entity)
{
}

protected override void RenderParticles()
{
if (!init)
{
init = true;
var m = ResourceCache.Instance.GetModel(ModelCacheKey);
if (m == null)
{
throw new InvalidResourceKeyException(nameof(ModelCacheKey), ModelCacheKey);
}
model = m.Value;

}
foreach (var particle in _particles)
{
model.Transform = Raymath.MatrixRotateXYZ(Raymath.QuaternionToEuler(particle.Rotation));
Raylib_cs.Raylib.DrawModelEx(model, particle.Position, Vector3.UnitY, 0, particle.Scale, particle.Color.ToRaylibColor());
}
}
}
}
8 changes: 8 additions & 0 deletions Basalt.Raylib/ExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,13 @@ public static EngineBuilder UseRaylibPreset(this EngineBuilder builder, WindowIn
builder.AddComponent<ISoundSystem, RaylibSoundSystem>();
return builder;
}


/// <summary>
/// Converts a <see cref="System.Drawing.Color"/> to a <see cref="Raylib_cs.Color"/>.
/// </summary>
/// <param name="color">The color to be converted to a raylib color type</param>
/// <returns>The original color as a <see cref="Raylib_cs.Color"/></returns>
public static Raylib_cs.Color ToRaylibColor(this System.Drawing.Color color) => new(color.R, color.G, color.B, color.A);
}
}
28 changes: 18 additions & 10 deletions Basalt.Raylib/Graphics/RaylibGraphicsEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class RaylibGraphicsEngine : IGraphicsEngine
private EntityManager entityManager;
private ISoundSystem? soundSystem;
private IEventBus eventBus;
private RayCameraController? cameraController;

Shader PostProcessShader, LightShader;
bool ShouldRun = true;
Expand Down Expand Up @@ -107,14 +108,19 @@ public unsafe void Initialize()
public unsafe void Render()
{
Camera3D camera = new();
var control = entityManager.GetEntities().FirstOrDefault(e => e.GetComponent<CameraController>() != null)?.GetComponent<CameraController>() ?? null;
var control = Engine.Instance.EntityManager.GetEntities().FirstOrDefault(e => e.GetComponents().FirstOrDefault(c => c.GetType().IsSubclassOf(typeof(RayCameraController))) is not null);
if (control == null)
{
throw new NullReferenceException("No camera controller found in the scene.");
Engine.Instance.Logger?.LogError("No camera controller found. Using default controller instead.");
var entity = new Entity();
entity.AddComponent(new FirstPersonCameraController(entity));
Engine.CreateEntity(entity);
cameraController = entity.GetComponent<FirstPersonCameraController>()!;
control = entity;
}

camera = control!.camera;
control.OnStart();
else
cameraController = control!.GetComponents().FirstOrDefault(c => c.GetType().IsSubclassOf(typeof(RayCameraController))) as RayCameraController;
camera = cameraController!.Camera;

RenderTexture2D target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());

Expand All @@ -140,7 +146,6 @@ public unsafe void Render()
// Main game loop
while (ShouldRun)
{
control.OnUpdate();
Time.DeltaTime = GetFrameTime();


Expand Down Expand Up @@ -173,7 +178,7 @@ public unsafe void Render()
foreach (var source in sources)
Rlights.UpdateLightValues(LightShader, source.Source);

SetShaderValue(LightShader, LightShader.Locs[(int)ShaderLocationIndex.VectorView], control.Entity.Transform.Position, ShaderUniformDataType.Vec3);
SetShaderValue(LightShader, LightShader.Locs[(int)ShaderLocationIndex.VectorView], cameraController.Entity.Transform.Position, ShaderUniformDataType.Vec3);
}

//----------------------------------------------------------------------------------
Expand All @@ -184,7 +189,7 @@ public unsafe void Render()
BeginTextureMode(target);
ClearBackground(Color.Black);

BeginMode3D(control.camera);
BeginMode3D(cameraController.Camera);

eventBus?.TriggerEvent(BasaltConstants.RenderEventKey);

Expand Down Expand Up @@ -259,13 +264,16 @@ public static T InvokeOnThread<T>(Func<T> delegateFunc)

private T invoke<T>(Func<T> delegateFunc) => delegateFunc();



public void Shutdown()
{
ShouldRun = false;
ResourceCache.Instance.UnloadRaylib();
logger?.LogWarning("Shutting down graphics engine...");
}

public void SetCameraController(RayCameraController newController)
{
cameraController = newController;
}
}
}
4 changes: 2 additions & 2 deletions Basalt.Raylib/Sound/RaylibSoundSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void Initialize()

private void UpdateStream(object? sender, EventArgs args)
{
if(MusicPlaying is not null)
if (MusicPlaying is not null)
{
UpdateMusicStream(MusicPlaying.Value);
}
Expand All @@ -49,7 +49,7 @@ public void Shutdown()
/// </summary>
/// <param name="logger">The logger to use for logging.</param>
public RaylibSoundSystem()
{
{
}

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions Basalt.TestField/Basalt.TestField.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 0 additions & 2 deletions Basalt.TestField/Components/DebugInfo.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
using Basalt.Common;
using Basalt.Common.Components;
using Basalt.Common.Entities;
using Raylib_cs;
using System.Diagnostics;
using static Raylib_cs.Raylib;

namespace Basalt.TestField.Components
Expand Down
2 changes: 1 addition & 1 deletion Basalt.TestField/Components/TestTrigger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public TestTrigger(Entity entity) : base(entity)

public override void OnCollision(Collider other)
{
if(other.Entity.Id == "entity.player")
if (other.Entity.Id == "entity.player")
{
Console.WriteLine($"Trigger collided with {other.Entity.Id}");
Entity.GetComponent<ModelRenderer>().ModelCacheKey = "sphere";
Expand Down
24 changes: 14 additions & 10 deletions Basalt.TestField/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
using Basalt.Raylib.Sound;
using Basalt.Raylib.Utils;
using Basalt.TestField;
using Basalt.TestField.Components;
using Basalt.Types;
using Raylib_cs;
using System.Numerics;
Expand Down Expand Up @@ -54,7 +53,7 @@


var player = new Entity();
player.AddComponent(new CameraController(player));
player.AddComponent(new FirstPersonCameraController(player));
player.Id = "entity.player";
Vector3 offset = Vector3.UnitY * -1;
player.Transform.Position = new Vector3(0, 5, 0);
Expand All @@ -66,15 +65,20 @@

Engine.CreateEntity(player);

var trigger = new Entity();
trigger.Id = "entity.trigger";
trigger.Transform.Position = new Vector3(10, 2.5f, 0);
trigger.AddComponent(new BoxCollider(trigger) { Size = new Vector3(5), IsTrigger = true });
trigger.AddComponent(new ModelRenderer(trigger) { ModelCacheKey = "cube", Size = new Vector3(5), ColorTint = Color.Blue });
trigger.AddComponent(new Rigidbody(trigger) { IsKinematic = true });
trigger.AddComponent(new TestTrigger(trigger));
Engine.CreateEntity(trigger);
var emitter = new Entity();
emitter.Transform.Position = new Vector3(0, 10, 0);
emitter.AddComponent(new RaylibParticleSystem(emitter) { ModelCacheKey = "cube" });
Engine.CreateEntity(emitter);

var ps = emitter.GetComponent<RaylibParticleSystem>()!;

ps.SubscribeOnParticleReset((ref Particle p) =>
{
p.Velocity = new(Random.Shared.NextSingle() * 10 - 5, Random.Shared.NextSingle() * 10 - 5, Random.Shared.NextSingle() * 10 - 5);
// Apply random rotation
p.Rotation = Quaternion.CreateFromYawPitchRoll(Random.Shared.NextSingle() * MathF.PI * 2, Random.Shared.NextSingle() * MathF.PI * 2, Random.Shared.NextSingle() * MathF.PI * 2);

});

TestingUtils.SetupTestingScene(250);
TestingUtils.SetupDebugInfo();
2 changes: 0 additions & 2 deletions Basalt.Tests/CircularBufferTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Basalt.Utility;
using NUnit.Framework;
using System;

namespace Basalt.Tests
{
Expand Down
11 changes: 9 additions & 2 deletions Basalt.Tests/Common/TestComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ public Entity? Target
}
}
}
public bool HasStarted;
public int OnStartCount = 0, OnUpdateCount = 0, OnRenderCount = 0, OnPhysicsUpdateCount = 0;
public bool HasStarted {get; set;}
public int OnStartCount { get; set; } = 0;
public int OnUpdateCount { get; set; } = 0;
public int OnRenderCount {get; set;} = 0;
public int OnPhysicsUpdateCount { get; set;} = 0;
public int Foo { get; private set; } = 0;
public override void OnStart()
{
HasStarted = true;
Expand All @@ -57,5 +61,8 @@ public override void OnPhysicsUpdate()
OnPhysicsUpdateCount++;
}

public int Get() => Foo;
public void Set(int value) => Foo = value;

}
}
Loading

0 comments on commit 1d2c3ae

Please sign in to comment.