junkerstock
 vrm-text-bvh19 

<!DOCTYPE html>
<html>
<head>
<title>VRM BVH Animation (Final Answer)</title>
<meta charset="utf-8">
<script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script>
<script src="./js/aframe-vrm.js"></script>

<script>
THREE.BVHLoader=function(){function e(t,n){const a=t.split(/[\s,]+/),r=[];for(let t=0;t<a.length;t++){const n=a[t];n.length>0&&r.push(n)}if("HIERARCHY"!==r.shift())throw new Error("Unexpected token: "+r.shift()+". Expected: HIERARCHY");if("ROOT"!==r.shift())throw new Error("Unexpected token: "+r.shift()+". Expected: ROOT");const o=i(r);if("MOTION"!==r.shift())throw new Error("Unexpected token: "+r.shift()+". Expected: MOTION");if("Frames:"!==r.shift())throw new Error("Unexpected token: "+r.shift()+". Expected: Frames:");const s=parseInt(r.shift());if(isNaN(s))throw new Error("Unexpected token: "+r.shift()+". Expected: A number.");if("Frame"!==r.shift())throw new Error("Unexpected token: ".concat(r.shift(),". Expected: Frame"));if("Time:"!==r.shift())throw new Error("Unexpected token: ".concat(r.shift(),". Expected: Time:"));const l=parseFloat(r.shift());if(isNaN(l))throw new Error("Unexpected token: "+r.shift()+". Expected: A number.");const c=[],u=[];o.traverse(function(e){n.animateBonePositions&&e.position.length>0&&u.push(new THREE.VectorKeyframeTrack(e.name+".position",e.position,e.position.length/3)),n.animateBoneRotations&&e.quaternion.length>0&&c.push(new THREE.QuaternionKeyframeTrack(e.name+".quaternion",e.quaternion,e.quaternion.length/4))});for(let t=0,n=0;t<s;t++){const a=parseFloat(r.splice(0,o.channels.length));n+=l,function t(n,a){const r=a.splice(0,n.channels.length);n.quaternion=new THREE.Quaternion;for(let o=0;o<n.channels.length;o++){const a=n.channels[o];switch(a){case"Xposition":n.position[0]=r[o];break;case"Yposition":n.position[1]=r[o];break;case"Zposition":n.position[2]=r[o];break;case"Xrotation":n.rotation.x=r[o];break;case"Yrotation":n.rotation.y=r[o];break;case"Zrotation":n.rotation.z=r[o]}}n.quaternion.setFromEuler(new THREE.Euler(THREE.MathUtils.degToRad(n.rotation.x),THREE.MathUtils.degToRad(n.rotation.y),THREE.MathUtils.degToRad(n.rotation.z),"XYZ")),n.children.forEach(e=>{t(e,a)})}(o,a)}const h=new THREE.Bone;return o.traverse(function(e){const t=new THREE.Bone;t.position.fromArray(e.offset),t.name=e.name,h.add(t)}),{skeleton:new THREE.Skeleton(h.children),clip:new THREE.AnimationClip("animation",-1,[...u,...c])}}function i(t){const e=t.shift(),n={name:e,offset:[],channels:[],children:[],position:[0,0,0],rotation:{x:0,y:0,z:0}};if("{"!==t.shift())throw new Error("Unexpected token: "+t.shift()+". Expected: {");for(;;){const a=t.shift();if("}"===a)break;if("OFFSET"===a)for(let a=0;a<3;a++){const r=parseFloat(t.shift());if(isNaN(r))throw new Error("Unexpected token: "+t.shift()+". Expected: A number.");n.offset.push(r)}else if("CHANNELS"===a){const a=parseInt(t.shift());if(isNaN(a))throw new Error("Unexpected token: "+t.shift()+". Expected: A number.");for(let r=0;r<a;r++)n.channels.push(t.shift())}else"JOINT"===a?n.children.push(i(t)):"End Site"===a&&n.children.push(i(t))}return n}return function(t){return Object.assign(Object.create(THREE.Loader.prototype),{constructor:t,animateBonePositions:!0,animateBoneRotations:!0,load:function(t,n,a,r){var o=this,s=new THREE.FileLoader(o.manager);s.setPath(o.path),s.setRequestHeader(o.requestHeader),s.setWithCredentials(o.withCredentials),s.load(t,function(t){n(o.parse(t))},a,r)},parse:function(t){return e(t,this)}})}(THREE.BVHLoader)}();
</script>

</head>
<body>
<a-scene>
<a-entity
id="avatar"
vrm="src: ./vrm/tesA1_V0a.vrm"
vrm-anim
position="0 0 0"
rotation="0 180 0">
</a-entity>
<a-camera position="0 1.2 2.5"></a-camera>
<a-sky color="#ECECEC"></a-sky>
</a-scene>

<script>
window.addEventListener('load', function() {
console.log('✅ ページ読み込み完了。BVHの処理を開始します。');

const BVH_URL = 'https://p-bookmark.sakura.ne.jp/junkerstock/vrm/8.bvh';
const avatarEl = document.querySelector('#avatar');

const boneMap = {
'J_Bip_C_Hips': 'hips', 'J_Bip_C_Spine': 'spine', 'J_Bip_C_Chest': 'chest',
'J_Bip_C_UpperChest': 'upperChest', 'J_Bip_C_Neck': 'neck', 'J_Bip_C_Head': 'head',
'J_Bip_L_Shoulder': 'leftShoulder', 'J_Bip_L_UpperArm': 'leftUpperArm',
'J_Bip_L_LowerArm': 'leftLowerArm', 'J_Bip_L_Hand': 'leftHand',
'J_Bip_R_Shoulder': 'rightShoulder', 'J_Bip_R_UpperArm': 'rightUpperArm',
'J_Bip_R_LowerArm': 'rightLowerArm', 'J_Bip_R_Hand': 'rightHand',
'J_Bip_L_UpperLeg': 'leftUpperLeg', 'J_Bip_L_LowerLeg': 'leftLowerLeg',
'J_Bip_L_Foot': 'leftFoot', 'J_Bip_L_ToeBase': 'leftToes',
'J_Bip_R_UpperLeg': 'rightUpperLeg', 'J_Bip_R_LowerLeg': 'rightLowerLeg',
'J_Bip_R_Foot': 'rightFoot', 'J_Bip_R_ToeBase': 'rightToes'
};

const loader = new THREE.BVHLoader();
loader.load(BVH_URL, function(bvh) {
console.log('✅ BVH読み込み成功。サンプル1のJSON形式に変換します。');

const bvhMotion = {};
const euler = new THREE.Euler();
const quaternion = new THREE.Quaternion();

bvh.clip.tracks.forEach(function(track) {
if (!track.name.endsWith('.quaternion')) {
return;
}

const bvhNodeName = track.name.split('.')[0];
const vrmBoneName = boneMap[bvhNodeName];

if (vrmBoneName) {
const keys = [];
for (let i = 0; i < track.times.length; i++) {
const time = track.times[i];

quaternion.fromArray(track.values, i * 4);
euler.setFromQuaternion(quaternion, 'YXZ');

keys.push({
rot: [
THREE.MathUtils.radToDeg(euler.x),
THREE.MathUtils.radToDeg(euler.y),
THREE.MathUtils.radToDeg(euler.z)
],
time: time
});
}
bvhMotion[vrmBoneName] = { keys: keys };
}
});

console.log('✅ 変換完了。待機モーションとしてモデルに適用します。');

// サンプル1と全く同じ方法で、生成したモーションデータを「待機モーション」として設定
avatarEl.setAttribute('vrm-anim', 'idleMotion', bvhMotion);

console.log('🎉 アニメーション適用完了!');
});
});
</script>

</body>
</html>


使用変数

) { console.log -------( Function )
a
avatarEl
boneMap
bvh) { console.log -------( Function )
BVHLoader
bvhMotion
bvhNodeName
BVH_URL
c
charset
color
e -------( Function )
e){const t=new THREE.Bone;t.position.fromArray -------( Function )
e){n.animateBonePositions&&e.position.length>0&&u.push -------( Function )
e
euler
h
i -------( Function )
i
id
keys
l
loader
n
name
o
position
quaternion
r
rotation
s
src
t -------( Function )
t){n -------( Function )
t){return e -------( Function )
t){return Object.assign -------( Function )
t,n,a,r){var o=this,s=new THREE.FileLoader -------( Function )
t
time
track) { if -------( Function )
u
vrm
vrmBoneName
x
y
z