Skip to content
/ mrjs Public
forked from Volumetrics-io/mrjs

An extensible WebComponents library for the Spatial Web

License

Notifications You must be signed in to change notification settings

bkcastro/mrjs

 
 

Repository files navigation

The mrjs logo

An extensible WebComponents library for the Spatial Web

npm run build npm run test License: MIT

Overview

mrjs is a mixed-reality-first, WebXR user interface library meant to bootstrap spatial web app development. It implements much of the foundational work so that developers can spend less time on the basics and more time on their app.

Main Links

  • landing-page - includes about, info, and high def and community-created samples
  • docs - includes onboarding information, engine setup (ECS, Contributing, etc), html tag helpers, and js-api documentation
  • dev-examples - the examples from the main mrjs repo used as dev explainers and for testing purposes

Getting started

Via a script tag in the <head> of your HTML file:

<head><script src="https://cdn.jsdelivr.net/npm/mrjs@latest/dist/mr.js"></script></head>

Via NPM:

npm i mrjs

From source:

You will need Node installed on your computer

First, clone this repository and then run:

npm install && npm run build

To test in headset:

npm run server

Documentation:

Check docs.mrjs.io for the full documentation or our repository.

For local documentation or to check the local output when writing your own PR to see how it will update, run the below command. As a heads up, order of creation of docs depends on your operating system, so if when you run this and the order looks different, no worries - in the repo itself our action will handle that for you and default to use the right version for these automatically generated docs.

npm run docs

HTTPS Requirement

In order to test on headset, WebXR requires that your project be served using an HTTPS server. If you're using WebPack you can achieve this by utilizing the DevServer webpack plugin with https: true.

Here are some additional solutions:

Both options require you generate an ssl certificate & key via openssl:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365

Features

Familiar 2D UI API

Create 2D UI using CSS and mr-panel

<style>
.layout {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr;
    gap: 10px;
    grid-auto-rows: minmax(100px, auto);
}
.title {
    margin: 0 auto;
    font-size: 5vw;
    line-height: 100%;
    color: rgba(24, 24, 24, 0.75);

    grid-column: 2;
}

mr-img {
    object-fit: cover;
    grid-row: 3 / 6;
    grid-column: 1 / -1;
}

#logo {
    grid-column : 2;
    scale: 0.001; /* set 3D content size */
    z-index: 100; /* set position on Z-axis */
}
</style>
<mr-app>
    <!-- The 2D UI Panel -->
    <mr-panel class="layout">
        <mr-text class="title">
            This is a quick example of an image gallery with explainer text.
        </mr-text>
        <mr-img src="..."></mr-img>
        <!--wrap non-UI components in mr-div to anchor to UI-->
        <mr-div id="logo">
            <mr-model src="./assets/models/logo.glb"></mr-model> 
        </mr-div>
    </mr-panel>
</mr-app>

Built-in Physics Engine

Rapier.js is fully integrated out of the box. We use it to power collision based hand-interactions, but also to support other common features such as:

  • Gravity
  • Rag doll physics
  • Joint constraints
  • Vehicles
  • Complex collision shapes
  • Kinematics

Extensible

Designed to be extensible, mrjs provides a familiar interface via THREE.js and the Custom Elements API, and leveled up with a built in ECS.

ECS

mrjs is designed from the ground up using the Entity-Component-System Architecture. This is a common architecture implemented by Game Engines such as Unity, Unreal, and Apple's RealityKit.

Entity

An Entity is an object. It stores only the most fundamental data, such as a unique identifier, a THREE.js Object3D, a physics body, and dimension data such as width and scale.

Any mr-* tag within the mr-app is an Entity. mr-entity is the spatial equivalent of a div.

Creating a custom Entity is as simple as creating a Custom Element via the WebComponents API.

Example:

class Spacecraft extends Entity {
    constructor(){
        this.object3D = this.generateSpacecraft()
    }

    // function to procedurally generate a 3D spacecraft
    generateSpacecraft(){
        ...
    }
}

customElements.get('mr-spacecraft') || customElements.define('mr-spacecraft', Spacecraft)

Systems

A System contains logic that is applied to all entities that have a corresponding Component, using the data stored by the component. Unlike Entities & Components, Systems have no HTML representation and are implemented entirely in JS.

When a component is attached or detatched from an entity, it is added or removed from its System's registry of entities.

Example:

class OrbitSystem extends System{
    constructor(){
        super()
    }

    // called every frame
    update(deltaTime, frame) {
        for(const entity in this.registry) {
            // Update entitiy position
            let component = entity.components.get('orbit')
            component.radius
            component.target
            //...
            entity.component.set('orbit', { speed : 1 })
        }
    }

    // Called when an orbit component is attached
    attachedComponent(entity) {
        //...
    }


    // do something when an orbit component is updated
    updatedComponent(entity, oldData) {
        //...
    }

    // do something when an orbit component is detatched
    detachedComponent(entity) {
        //...
    }
}

When you define a custom system, it listens for events triggered when the System's corresponding component is attached, updated, or detatched. in the above case, data-comp-orbit.

Components

Components are attached to entities and used to store data. in mrjs they are implemented using data attributes beginning with the prefix data-comp-.

Example:

<mr-spacecraft data-comp-orbit="radius: 0.5; target: #user;"></mr-spacecraft>

Note: the mapping between components and systems is 1-to-1, and the naming convention (data-comp-<name> and <Name>System) is strictly enforced.

About

An extensible WebComponents library for the Spatial Web

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 99.5%
  • CSS 0.5%