I have a website where I need to create a 3d plane object which have provided image as texture on two sides. Then I want to render that object into matterport scene/space.
Note: I cannot export the glb file as the object has to be created on the website and rendered on the matterport scene. The glb file isnot stored anywhere on the database, It is created from the provided image.
I have implemented the logic of creating plane 3d object and exporting to glb file having image as texture using three js as:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Loading 3d models</title>
<style>
body {
margin: 0;
}
canvas {
display: block;
}
</style>
</head>
<body>
<p>
<span><button class="export-glb">Export</button></span>
</p>
<script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import { GLTFExporter } from "three/addons/exporters/GLTFExporter.js";
const exportBtn = document.querySelector(".export-glb"); // Create export button dynamically
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Load the water texture
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("test-3.png");
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
// Create a plane geometry and apply the texture as material
const geometry = new THREE.PlaneGeometry(1, 1);
const material = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.DoubleSide, // Makes the texture visible from both sides
transparent: true,
});
const plane = new THREE.Mesh(geometry, material);
scene.add(plane);
// OrbitControls for better interaction
const controls = new OrbitControls(camera, renderer.domElement);
camera.position.z = 5;
function animate() {
renderer.render(scene, camera);
controls.update();
}
renderer.setAnimationLoop(animate);
// Function to download the scene as a GLB file
function download() {
const exporter = new GLTFExporter();
exporter.parse(
scene,
function (result) {
if (result instanceof ArrayBuffer) {
console.log("result", result);
saveArrayBuffer(result, "scene.glb");
} else {
console.error(
"GLTFExporter did not return an ArrayBuffer. Converting to GLB format..."
);
const json = JSON.stringify(result);
console.log(result);
const buffer = new TextEncoder().encode(json);
saveArrayBuffer(buffer, "scene.glb"); // Save as .glb but it will be in JSON format
}
},
{ binary: true }
);
}
// Function to save the ArrayBuffer as a file
function saveArrayBuffer(buffer, filename) {
const blob = new Blob([buffer], { type: "application/octet-stream" });
const link = document.createElement("a");
link.style.display = "none";
document.body.appendChild(link); // Firefox workaround
link.href = URL.createObjectURL(blob);
link.download = filename;
link.click();
}
// Add event listener for the export button
exportBtn.addEventListener("click", download);
</script>
</body>
</html>
And I know to render the glb files in matterport too.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>load</title>
<link rel="stylesheet" />
</head>
<body>
<iframe
id="showcase"
width="100%"
height="700"
src="./bundle/showcase.html?m=gMDfBc11wvm&applicationKey=<YOUR_MATTERPORT_SDK_KEY>&play=1"
frameborder="”0”"
allowfullscreen
allow="vr"
></iframe>
<script>
const bundleIframe = document.getElementById("showcase");
const showcaseWindow = bundleIframe.contentWindow;
let mpSdk;
let mattertagID;
showcase.addEventListener("load", async function () {
try {
mpSdk = await showcaseWindow.MP_SDK.connect(showcaseWindow);
console.log("mpSdk", mpSdk);
const [sceneObject] = await mpSdk.Scene.createObjects(1);
const lights = sceneObject.addNode();
lights.addComponent("mp.lights");
lights.start();
const modelNode = sceneObject.addNode();
// Store the glb component since we will need to adjust it in the next step.
const fbxComponent = modelNode.addComponent(
mpSdk.Scene.Component.GLTF_LOADER,
{
url: "water.glb",
}
);
fbxComponent.inputs.localScale = {
x: 0.2,
y: 0.2,
z: 0.2,
};
modelNode.obj3D.position.set(-1, 1, 0); // drop ~3 feet
modelNode.start();
const tick = function () {
requestAnimationFrame(tick);
modelNode.obj3D.rotation.y += 0.02;
};
tick();
} catch (e) {
console.log("error", e);
}
});
</script>
</body>
</html>
Any suggestions or example of such implementation would be helpful.
Thanks in advance <3 .