Skip to content

Instantly share code, notes, and snippets.

@Keshigom
Created June 30, 2020 11:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Keshigom/2d32b05bd810a001ad768774c0b3d78d to your computer and use it in GitHub Desktop.
Save Keshigom/2d32b05bd810a001ad768774c0b3d78d to your computer and use it in GitHub Desktop.
AR.jsのNFTでVRMモデルを表示する
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<!-- three.js library -->
<script src='lib/three.min.js'></script>
<!-- three.js load GLTF -->
<script src='lib/GLTFLoader.js'></script>
<!-- ar.js -->
<script src='lib/ar-nft.js'></script>
<!-- three-vrm -->
<script src="lib/three-vrm.min.js"></script>
<script>THREEx.ArToolkitContext.baseURL = '../'</script>
<body style='position: absolute; top: 0; left: 0; width: 100%; height: 100%; margin : 0px; overflow: hidden;'>
<style>
.arjs-loader {
margin: 0 auto;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
}
.arjs-loader-spinner {
z-index: 10;
-webkit-transform: spin 1s linear infinite;
animation: spin 1s linear infinite;
border: 3px solid #ddd;
border-top: 3px solid #42a5f5;
border-radius: 50%;
height: 75px;
width: 75px;
}
@-webkit-keyframes spin {
to {
border-top-color: #42a5f5;
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spin {
to {
border-top-color: #42a5f5;
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
</style>
<div class="arjs-loader">
<div class="arjs-loader-spinner"></div>
</div>
<script>
var renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
logarithmicDepthBuffer: true,
});
var clock = new THREE.Clock();
var mixers = [];
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setClearColor(new THREE.Color('lightgrey'), 0)
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.domElement.style.position = 'absolute'
renderer.domElement.style.top = '0px'
renderer.domElement.style.left = '0px'
document.body.appendChild(renderer.domElement);
var scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1000, 10000);
scene.add(camera);
const light = new THREE.DirectionalLight(0xffffff);
light.position.set(1.0, 1.0, 1.0).normalize();
scene.add(light);
var arToolkitSource = new THREEx.ArToolkitSource({
sourceType: 'webcam',
sourceWidth: 480,
sourceHeight: 640,
})
arToolkitSource.init(function onReady() {
// use a resize to fullscreen mobile devices
setTimeout(function () {
onResize()
}, 1000);
})
// handle resize
window.addEventListener('resize', function () {
onResize()
})
// listener for end loading of NFT marker
window.addEventListener('arjs-nft-loaded', function (ev) {
console.log(ev);
})
function onResize() {
arToolkitSource.onResizeElement()
arToolkitSource.copyElementSizeTo(renderer.domElement)
if (arToolkitContext.arController !== null) {
arToolkitSource.copyElementSizeTo(arToolkitContext.arController.canvas)
}
}
// create atToolkitContext
var arToolkitContext = new THREEx.ArToolkitContext({
detectionMode: 'mono',
canvasWidth: 480,
canvasHeight: 640,
}, {
sourceWidth: 480,
sourceHeight: 640,
})
// initialize it
arToolkitContext.init(function onCompleted() {
// copy projection matrix to camera
camera.projectionMatrix.copy(arToolkitContext.getProjectionMatrix());
})
var root = new THREE.Group();
scene.add(root);
// init controls for camera
var markerControls = new THREEx.ArMarkerControls(arToolkitContext, camera, {
type: 'nft',
descriptorsUrl: 'data/dataNFT/marker',
changeMatrixMode: 'cameraTransformMatrix'
})
scene.visible = true
const loader = new THREE.GLTFLoader();
loader.load(
// URL of the VRM you want to load
'data/model.vrm',
// called when the resource is loaded
(gltf) => {
// generate a VRM instance from gltf
THREE.VRM.from(gltf).then((vrm) => {
const scale = 200;
// add the loaded vrm to the scene
vrm.scene.scale.set(scale, scale, scale);
// root.matrixAutoUpdate = false;
root.add(vrm.scene);
vrm.scene.rotation.y = Math.PI;
vrm.scene.position.x = 80;
vrm.scene.position.z = -80;
loadJson("./data/data/pose.json", (json) => {
vrm.humanoid.setPose(json);
});
// deal with vrm features
console.log(vrm);
});
},
// called while loading is progressing
(progress) => console.log('Loading model...', 100.0 * (progress.loaded / progress.total), '%'),
// called when loading has errors
(error) => console.error(error)
);
const animate = () => {
requestAnimationFrame(animate);
if (!arToolkitSource.ready) {
return;
}
arToolkitContext.update(arToolkitSource.domElement)
// update scene.visible if the marker is seen
scene.visible = camera.visible;
renderer.render(scene, camera);
};
requestAnimationFrame(animate);
const loadJson = (path, callback) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
callback(xhr.response);
}
};
xhr.responseType = 'json';
xhr.open('GET', path, true);
xhr.send();
};
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment