Skip to content

Commit f3464f3

Browse files
author
Avaer Kazmer
committed
Add initial RiggedModel hack, not accurate or good as a basis for
anything
1 parent c85632d commit f3464f3

File tree

1 file changed

+42
-142
lines changed

1 file changed

+42
-142
lines changed

app.html

Lines changed: 42 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,22 @@
352352
subtree: true,
353353
});
354354

355+
class RiggedModel {
356+
constructor(avatarMesh) {
357+
this.avatarMesh = avatarMesh;
358+
}
359+
setState(hmd, gamepads) {
360+
this.avatarMesh.position.fromArray(hmd.position).sub(localVector.set(0, 1.5, 0));
361+
localQuaternion.fromArray(hmd.quaternion);
362+
localEuler.setFromQuaternion(localQuaternion, localEuler.order);
363+
localEuler.y += Math.PI;
364+
localEuler.x *= -1;
365+
this.avatarMesh.quaternion.setFromEuler(localEuler);
366+
}
367+
update() {
368+
// console.log('per-frame update called');
369+
}
370+
}
355371
const _makePeerConnection = peerConnectionId => {
356372
const peerConnectionConfig = {
357373
iceServers: [
@@ -365,17 +381,27 @@
365381
console.log('got track', e);
366382
};
367383

368-
let skinMesh = null;
384+
let avatarMesh = null;
369385
const sendChannel = peerConnection.createDataChannel('sendChannel');
370386
peerConnection.sendChannel = sendChannel;
371387
let pingInterval = 0;
372388
let updateInterval = 0;
373389
sendChannel.onopen = () => {
374390
// console.log('data channel local open');
375391

376-
skinMesh = _makeSkinMesh();
377-
skinMesh.setSkinUrl(DEFAULT_SKIN_URL);
378-
skinMeshes.push(skinMesh);
392+
avatarMesh = new THREE.Object3D();
393+
avatarMesh.riggedModel = null;
394+
const loader = new THREE.GLTFLoader();
395+
loader.load('https://modulesio.github.io/models/miku.glb', object => {
396+
if (avatarMesh) {
397+
avatarMesh.riggedModel = new RiggedModel(object.scene);
398+
avatarMesh.add(object.scene);
399+
}
400+
}, xhr => {}, err => {
401+
console.warn(err);
402+
});
403+
scene.add(avatarMesh);
404+
avatarMeshes.push(avatarMesh);
379405

380406
peerConnection.open = true;
381407

@@ -459,9 +485,9 @@
459485
const data = JSON.parse(e.data);
460486
const {method} = data;
461487
if (method === 'pose') {
462-
if (skinMesh) {
488+
if (avatarMesh && avatarMesh.riggedModel) {
463489
const {hmd, gamepads} = data;
464-
skinMesh.setState(hmd, gamepads);
490+
avatarMesh.riggedModel.setState(hmd, gamepads);
465491
}
466492
} else if (landState && method === 'initState') {
467493
const {state} = data;
@@ -507,10 +533,10 @@
507533
if (index !== -1) {
508534
peerConnections.splice(index, 1);
509535
}
510-
if (skinMesh) {
511-
skinMesh.destroy();
512-
skinMeshes.splice(skinMeshes.indexOf(skinMesh), 1);
513-
skinMesh = null;
536+
if (avatarMesh) {
537+
scene.remove(avatarMesh);
538+
avatarMeshes.splice(avatarMeshes.indexOf(avatarMesh), 1);
539+
avatarMesh = null;
514540
}
515541
if (landState) {
516542
// remove owned xr-iframes
@@ -6095,12 +6121,13 @@
60956121
};
60966122
_updateSceneMeshes(); */
60976123

6098-
const _updateSkinMeshes = () => {
6099-
for (let i = 0; i < skinMeshes.length; i++) {
6100-
skinMeshes[i].update();
6124+
const _updateAvatarMeshes = () => {
6125+
for (let i = 0; i < avatarMeshes.length; i++) {
6126+
const avatarMesh = avatarMeshes[i];
6127+
avatarMesh.riggedModel && avatarMesh.riggedModel.update();
61016128
}
61026129
};
6103-
_updateSkinMeshes();
6130+
_updateAvatarMeshes();
61046131

61056132
const _handleTrigger = (gamepad, i, pressed, lastPressed) => {
61066133
const start = pressed && !lastPressed;
@@ -6870,139 +6897,12 @@
68706897
console.warn(err.stack);
68716898
});
68726899

6873-
const skinMeshes = [];
6900+
const avatarMeshes = [];
68746901
const _mod = (v, d) => {
68756902
const n = v % d;
68766903
return n < 0 ? (d + n) : n;
68776904
};
68786905
const _angleDiff = (a, b) => _mod((b - a) + Math.PI, Math.PI * 2) - Math.PI;
6879-
const _makeSkinMesh = () => {
6880-
const object = {};
6881-
let onsetstate = null;
6882-
const uniforms = THREE.UniformsUtils.clone(skin.SKIN_SHADER.uniforms);
6883-
object.setSkinUrl = skinUrl => {
6884-
if (skinUrl) {
6885-
const mesh = skin({
6886-
limbs: true,
6887-
});
6888-
mesh.frustumCulled = false;
6889-
6890-
mesh.onBeforeRender = (onBeforeRender => function() {
6891-
mesh.material.uniforms.headRotation.value.copy(uniforms.headRotation.value);
6892-
mesh.material.uniforms.leftArmRotation.value.copy(uniforms.leftArmRotation.value);
6893-
mesh.material.uniforms.rightArmRotation.value.copy(uniforms.rightArmRotation.value);
6894-
mesh.material.uniforms.theta.value = uniforms.theta.value;
6895-
mesh.material.uniforms.headVisible.value = uniforms.headVisible.value;
6896-
mesh.material.uniforms.hit.value = uniforms.hit.value;
6897-
6898-
onBeforeRender.apply(this, arguments);
6899-
})(mesh.onBeforeRender);
6900-
6901-
return new Promise((accept, reject) => {
6902-
const skinImg = new Image();
6903-
skinImg.crossOrigin = 'Anonymous';
6904-
skinImg.src = skinUrl;
6905-
skinImg.onload = () => {
6906-
accept(skinImg);
6907-
};
6908-
skinImg.onerror = err => {
6909-
reject(err);
6910-
};
6911-
})
6912-
.then(skinImg => {
6913-
mesh.setImage(skinImg);
6914-
6915-
onsetstate = (hmd, gamepads) => {
6916-
const hmdPosition = localVector.fromArray(hmd.position);
6917-
const hmdQuaternion = localQuaternion.fromArray(hmd.quaternion);
6918-
6919-
const hmdEuler = localEuler.setFromQuaternion(hmdQuaternion, localEuler.order);
6920-
const playerEuler = localEuler2.setFromQuaternion(mesh.quaternion, localEuler2.order);
6921-
const angleDiff = _angleDiff(hmdEuler.y, playerEuler.y);
6922-
const angleDiffAbs = Math.abs(angleDiff);
6923-
if (angleDiffAbs > Math.PI / 2) {
6924-
playerEuler.y += (angleDiffAbs - (Math.PI / 2)) * (angleDiff < 0 ? 1 : -1);
6925-
mesh.quaternion.setFromEuler(playerEuler);
6926-
}
6927-
6928-
const oldWorldPosition = mesh.getWorldPosition(localVector2);
6929-
mesh.position.copy(hmdPosition)
6930-
.sub(mesh.eye.getWorldPosition(localVector3))
6931-
.add(oldWorldPosition);
6932-
6933-
const playerQuaternionInverse = localQuaternion2.copy(mesh.quaternion).inverse();
6934-
mesh.head.quaternion.copy(playerQuaternionInverse).multiply(hmdQuaternion);
6935-
mesh.updateMatrixWorld();
6936-
6937-
const headQuaternionInverse = localQuaternion3.copy(mesh.head.quaternion).inverse();
6938-
uniforms.headRotation.value.set(headQuaternionInverse.x, headQuaternionInverse.y, headQuaternionInverse.z, headQuaternionInverse.w);
6939-
6940-
for (let i = 0; i < 2; i++) {
6941-
const armRotation = uniforms[i === 0 ? 'leftArmRotation' : 'rightArmRotation'];
6942-
6943-
const gamepad = gamepads[i];
6944-
if (gamepad.visible) {
6945-
const gamepadPosition = localVector.fromArray(gamepad.position);
6946-
const gamepadQuaternion = localQuaternion.fromArray(gamepad.quaternion);
6947-
6948-
const armQuaternionInverse = localQuaternion3.setFromRotationMatrix(
6949-
localMatrix.lookAt(
6950-
mesh.arms[i === 0 ? 'left' : 'right']
6951-
.getWorldPosition(localVector2),
6952-
gamepadPosition,
6953-
localVector3
6954-
.set(0, 1, 0)
6955-
.applyQuaternion(gamepadQuaternion)
6956-
)
6957-
)
6958-
.multiply(armQuaternionOffset)
6959-
.premultiply(playerQuaternionInverse)
6960-
.inverse();
6961-
armRotation.value.set(armQuaternionInverse.x, armQuaternionInverse.y, armQuaternionInverse.z, armQuaternionInverse.w);
6962-
// console.log('arm rotation', i, armRotation.value.toArray().join(','));
6963-
} else {
6964-
armRotation.value.set(0, 0, 0, 1);
6965-
}
6966-
}
6967-
};
6968-
6969-
if (object.skinMesh) {
6970-
object.skinMesh.parent.remove(object.skinMesh);
6971-
object.skinMesh = null;
6972-
}
6973-
6974-
scene.add(mesh);
6975-
object.skinMesh = mesh;
6976-
});
6977-
} else {
6978-
onsetstate = null;
6979-
6980-
if (object.skinMesh) {
6981-
object.skinMesh.parent.remove(object.skinMesh);
6982-
object.skinMesh = null;
6983-
}
6984-
}
6985-
};
6986-
object.setState = (hmd, gamepads) => {
6987-
onsetstate && onsetstate(hmd, gamepads);
6988-
};
6989-
object.animate = thetaValue => {
6990-
uniforms.theta.value = thetaValue;
6991-
};
6992-
object.update = () => {
6993-
// XXX
6994-
};
6995-
object.destroy = () => {
6996-
onsetstate = null;
6997-
6998-
if (object.skinMesh) {
6999-
object.skinMesh.parent.remove(object.skinMesh);
7000-
object.skinMesh = null;
7001-
}
7002-
};
7003-
object.skinMesh = null;
7004-
return object;
7005-
};
70066906

70076907
scene.add(defaultGltf);
70086908
const _loadDefaultGltf = () => {

0 commit comments

Comments
 (0)