Friday, January 26, 2024

EduXR - The XR Micro Learning Platform

Introducing our cutting-edge Augmented Reality (AR) educational application designed to revolutionize the learning experience for students across various courses and classes. This versatile app aligns seamlessly with official school curricula, offering an immersive journey through interactive experiments that bring abstract concepts to life.


Key Features:

Multi-Course Compatibility: Our AR application covers a spectrum of subjects, ensuring a comprehensive educational experience across diverse disciplines. From physics to biology, chemistry to mathematics, students can explore and understand each course with captivating augmented reality simulations.

Official Curriculum Integration: Aligned with official school curricula, the app ensures that students are learning in line with educational standards. The content is curated to enhance understanding and complement classroom teachings, providing a supplementary, interactive layer to the traditional learning process.

Multi-Year/Class Support: Tailored to cater to students of various levels, the app spans multiple years and classes. Whether you're a high school freshman or a senior, the AR experience evolves to meet the complexity and depth of the subjects studied, ensuring a continuous and progressive learning journey.

Multilingual Interface: Breaking down language barriers, our application supports multiple languages, making it accessible to a global audience. Students can learn and engage in their preferred language, fostering inclusivity and facilitating a more personalized learning experience.

Cross-Platform Compatibility: Our commitment to accessibility is reflected in the app's compatibility with multiple mobile platforms. Whether you use iOS or Android, our AR application is designed to function seamlessly on your device, bringing the wonders of augmented reality education to your fingertips.

Interactive Assessments: At the conclusion of each course or class, students can assess their understanding through interactive tests within the app. These assessments not only gauge knowledge retention but also provide instant feedback, including a percentage score. This feature empowers students to track their progress and reinforces the concepts learned in a dynamic and engaging manner.

Embark on an educational journey like never before with our AR application, where learning transcends traditional boundaries, and understanding is achieved through immersive experiences. 


Welcome to the future of education!




Wednesday, May 31, 2023

Micro API Design Pattern

 Hello there,

From the architectural/design point of view these are the common API design patterns:

  • monolith - all endpoints in one project (or dependencies)
  • micro services - separated by domain (and with specific components such as service registry or API gateway).

These have their own pros and cons and I would like to propose a hybrid approach - Micro APIs.

Technically, all micro APIs are hosted in a monolith but are not loaded as a normal dependencies - they are discovered at runtime. This approach is using the plugin-based design but applied to APIs. Basically, one can have all the benefits from the micro-services architectural/design pattern (as the micro APIs/plugins can be developed per domain and with different technologies, as long as the host can handle them) and still be manageable as a monolith (of course, this will not stop the host to be scaled and I think that sometimes a smart load balancer may redirect the traffic to the nodes that are domain specific, hence micro service).

Each micro API will have it's own API endpoints handlers (e.g. controllers), services and data models (aka DTO, ViewModels, etc.). Using patterns like dependency injection each micro API can use services from the host, if needed (e.g. configuration, logging, etc.).

A micro API project might look like this:


An ASP.NET Core/6/7 implementation might look like this:

1/ At Startup.cs the host will try to discover the plugins from some location (this can be changed if needed).

RegisterPlugins(services);
private void RegisterPlugins(IServiceCollection serviceCollection)
{
    var pluginsPath = Path.Combine(AppContext.BaseDirectory@".\Plugins");
    string[] pluginPaths = Directory.GetFiles(pluginsPath"*.Plugin.dll"SearchOption.AllDirectories);
    var pluginAssemblies = pluginPaths.Select(pluginPath => pluginPath.LoadAssembly());
 
    foreach (var assembly in pluginAssemblies)
    {
        assembly.LoadBaseServices(serviceCollection);
        serviceCollection.AddAutoMapper(assembly);
 
        serviceCollection.AddControllers()
            .PartManager.ApplicationParts.Add(new AssemblyPart(assembly));
    }
 
    // init plugins
    var serviceProvider = serviceCollection.BuildServiceProvider();
    var registrars = serviceProvider.GetServices<IServiceRegistrar>();
 
    foreach (var registrar in registrars)
    {
        registrar.Register(serviceCollection);
    }
}

This will try to load all plugins and add the controllers as an application part.

2/ In order to use DI, a micro API would have to implement an IServiceRegistrar interface where all the DI services from that micro API will be registered in the services collection.

public interface IServiceRegistrar
{
    void Register(IServiceCollection services); 

}

public sealed class ServiceRegistrar : IServiceRegistrar
 {
     public void Register(IServiceCollection services)
     {
         services.AddScoped<IMaptServiceMaptService>();
     } 

 } 

3/ The micro API controllers will be the normal ASP.NET Core/6/7 controllers - no changes here.

[ApiController]
[Route("api/[controller]")]
[Authorize]
public class MaptController : ControllerBase
{
    readonly IMapper _mapper;
    readonly IMaptService _maptService;
 
    public MaptController(IMapper mapperIMaptService maptService)
    {
        _mapper = mapper;
        _maptService = maptService;
    }
 
    [HttpGet]
    public IActionResult Get()
    {
        return StatusCode(200new MaptViewModel { Result = "OK" });
    }
}

4/ If you now run the WebAPI host and enable Swagger (e.g. Swashbuckle.AspNetCore) you will notice that even if the micro API project is not statically linked/referred by the WebAPI host, the micro APIs endpoints will appear in the Swagger documentation and will be available to be consumed.

If an existing micro API is removed then the impact on the host is minimal or non-existing (the host is auto-cleaning). Same for adding a micro API, the host will load it in it's memory context and expose any endpoints of the micro API.

Hope this will help you in designing new ways of consuming APIs!

Happy Coding!


The helper functions (which can be part of a common project/assembly):

public class PluginLoadContext : AssemblyLoadContext
    {
        private AssemblyDependencyResolver _resolver;
 
        public PluginLoadContext(string pluginPath)
        {
            _resolver = new AssemblyDependencyResolver(pluginPath);
        }
 
        protected override Assembly Load(AssemblyName assemblyName)
        {
            string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName);
            if (assemblyPath != null)
            {
                return LoadFromAssemblyPath(assemblyPath);
            }
 
            return null;
        }
 
        protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
        {
            string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName);
            if (libraryPath != null)
            {
                return LoadUnmanagedDllFromPath(libraryPath);
            }
 
            return IntPtr.Zero;
        }
    }


public static class PluginHelpers
{
    public static Assembly LoadAssembly(this string path)
    {
        string pluginLocation = Path.GetFullPath(path);
        return new PluginLoadContext(pluginLocation).LoadFromAssemblyName(AssemblyName.GetAssemblyName(pluginLocation));
    }
 
    public static void LoadBaseServices(this Assembly assemblyIServiceCollection services)
    {
        foreach (Type type in assembly.GetTypes())
        {
            if (typeof(ICommand).IsAssignableFrom(type))
            {
                services.AddSingleton(typeof(ICommand), type);
            }
            if (typeof(IServiceRegistrar).IsAssignableFrom(type))
            {
                services.AddSingleton(typeof(IServiceRegistrar), type);
            }
        }
    } } 

Wednesday, April 6, 2022

SteamVR Input in MRTK 2.6 and later

 Hello,

I've seen a lot of interest on this topic and I would like to put the info in one place.

First, you need to download SteamVR asset and use my implementation of SteamVR XRSDK Device Manager and controllers from here.

There are two parts: one is in SteamVR and one is in MRTK. 
If you already know the actions you need for SteamVR, then you need to generate the SteamVR_Input action classes (these are used by the custom implementation of the SteamVR layer in MRTK) by going to Unity Editor menu, Windows -> SteamVR Input and hit Generate. If you need to change the bindings, you will need to create the bindings in the bindings UI.




Then, you need to add the SteamVR XRSDK manager to data providers and use the Player prefab from SteamVR - this will give you the avatar hands (ofc, you can create a separate one with whatever hands you want but you will need to animate that).


Then you need to add SteamVRXRSDKControllers in the Controller Definitions area.


 
Then you need to alter input mappings for the Generic OpenVR Controller Definitions (if you plan to add specific actions - in my case I used Touchpad click as Select):



Then you need to Update mappings by going to Unity Editor and in the menu: Mixed Reality Toolkit -> Update -> Controller mappings profiles. This will update some assets from MRTK.

Then you need to activate the SteamVR for MRTK by adding the preprocessor directive STEAMVR_INTEGRATION in Unity Editor/Player/Other.



Finally, you need to activate the OpenVR Loader in XR Management.



If you hit Play in Editor, the app will start and you should see the MRTK default gizmo controllers synced with the SteamVR avatar hands.

That's about it!

Have fun!

Tuesday, July 23, 2019

ReplayVR - Support page

Hey there,

This is the page for ReplayVR asset. Checkout the ReplayVR-Demo project on Github: https://github.com/eusebiu/ReplayVR-Demo

Please add your comments or requests in the comments section or on the github issues page.

Thank you!