I need to blog more. It’s such a great way to document a project and maintain confidence that things are actually happening. I’ve been thinking a lot about the role WordPress and systems like 3OV will play in the pursuit of an open metaverse. It occurred to me the most important thing to secure a vibrant future for 3OV will be extendability. People want to do custom stuff almost immediately when using 3D apps. It’s one of the most common questions I get about this plugin. The spirit of modding is in all of us!
In the last month I shifted focus to the Pro version of the plugin which led to the imagining of an open system where 3OV users (as well as myself) can create and distribute their own custom 3D Blocks. This can be complex when using WordPress innerBlocks due to the unpredictable nature of third party generated content, but in the last few days I have been able to successfully build a framework that allows anyone to inject custom Three.js components into the 3OV app context from a separately registered script and Block. Before I get into the system and the code, I’ll preface, when this launches I will provide a boilerplate and CLI command to generate custom 3OV blocks. All you’ll need to do is focus on Three.js code. Before all that, I’ll need to walk the walk by using this system to build 3OV Pro.
The first Pro block I mocked up to demonstrate this system is a Mirror Block which allows you to set a size and position for a mirror entity to render in world. There are two contexts that can have injected components, Editor View and Front View. In the following screenshot I demonstrate how a Mirror Block is being added from outside of the 3OV Core plugin with all the custom attributes you need defined in the sidebar. The editor view allows you to have a separate component that is more relevant to the editing experience. You can certainly use the same component for both editor and front end but the option is there.
The following snippet demonstrates the editor side plugin registration in the Edit.js
of a custom 3OV block:
export default function Edit({ attributes, setAttributes, isSelected, clientId }) {
window.addEventListener('registerEditorPluginReady', function() {
window.registerEditorPlugin(
<ThreeMirror props />
);
});
Code language: JavaScript (javascript)
Where <ThreeMirror>
renders in the editor as the following:
import React, { useState, useRef } from "react";
import { Reflector } from 'three/examples/jsm/objects/Reflector';
import {
PlaneGeometry,
Color,
} from "three";
export function ThreeMirror(threeMirror) {
const mirrorObj = useRef();
const mirrorBlockAttributes = wp.data
.select("core/block-editor")
.getBlockAttributes(threeMirror.pluginObjectId);
const mirror = new Reflector(
new PlaneGeometry(10, 10), { color: new Color(0x7f7f7f) }
);
return (
<group
ref={mirrorObj}
position={ mirrorBlockAttributes.position }
rotation={ mirrorBlockAttributes.rotation }
scale={ mirrorBlockAttributes.scale }
>
<primitive object={mirror} />
</group>
);
}
Code language: JavaScript (javascript)
For the frontend, you can enqueue Javascript to register the front plugin. The following is a script that shows very simply how a plugin can be registered from the frontend Javascript of a newly added innerBlock:
import React, { useEffect } from 'react';
import { Reflector } from 'three/examples/jsm/objects/Reflector';
import { PlaneGeometry, Color } from "three";
// Even drei components.
function ThreeMirrorBlockRender(props) {
const mirror = new Reflector(
new PlaneGeometry(10, 10), { color: new Color(0x7f7f7f) }
);
return (
<group
position={props.position}
rotation={props.rotation}
scale={props.scale}
>
<primitive object={mirror} />
</group>
)
}
// Wait for the plugin system to be ready and register this plugin.
window.addEventListener('registerFrontPluginReady', function() {
window.registerFrontPlugin(<ThreeMirrorBlockRender />);
});
Code language: JavaScript (javascript)
In the above scripts we wait for the plugin systems to be ready to accept outside components to add in world. Essentially any vanilla Three.js code can happen here including animations! This is proving to be a huge upgrade for 3OV that will set a foundation for limitless possibilities. This was a bit of a brain dump but I hope it illustrates how you’ll be able to extend 3OV in a very near future. Onward!