From e6bc0b74becb84799131abfe3f30cf63511ea482 Mon Sep 17 00:00:00 2001 From: memelotsqui Date: Sat, 28 Oct 2023 01:59:40 -0600 Subject: [PATCH 1/4] escport vrm0 with mvoed joints --- src/components/Selector.jsx | 34 ++++++++++++++++++++++--- src/library/merge-geometry.js | 48 ++++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/components/Selector.jsx b/src/components/Selector.jsx index b9e54ae8..0308ae68 100644 --- a/src/components/Selector.jsx +++ b/src/components/Selector.jsx @@ -473,6 +473,24 @@ export default function Selector({confirmDialog, templateInfo, animationManager, return typeTraits; } + const rotateMeshVerticesY = (mesh, angle) => { + const vertices = mesh.geometry.attributes.position.array; + + for (let i = 0; i < vertices.length; i += 3) { + const x = vertices[i]; + const z = vertices[i + 2]; + + // Apply rotation around the Y-axis + const rotatedX = x * Math.cos(angle) - z * Math.sin(angle); + const rotatedZ = x * Math.sin(angle) + z * Math.cos(angle); + + vertices[i] = rotatedX; + vertices[i + 2] = rotatedZ; + } + + mesh.geometry.attributes.position.needsUpdate = true; + } + // once loaded, assign const itemAssign = (itemData) => { const item = itemData.item; @@ -508,10 +526,8 @@ export default function Selector({confirmDialog, templateInfo, animationManager, let vrm = null models.map((m)=>{ - - // basic vrm setup (only if model is vrm) vrm = m.userData.vrm; - + if (getAsArray(templateInfo.lipSyncTraits).indexOf(traitData.trait) !== -1) setLipSync(new LipSync(vrm)); renameVRMBones(vrm) @@ -600,7 +616,17 @@ export default function Selector({confirmDialog, templateInfo, animationManager, child.geometry.computeBoundsTree({strategy:SAH}); createFaceNormals(child.geometry) - if (child.isSkinnedMesh) createBoneDirection(child) + if (child.isSkinnedMesh) { + createBoneDirection(child) + if (vrm.meta?.metaVersion === '0'){ + VRMUtils.rotateVRM0( vrm ); + for (let i =0; i < child.skeleton.bones.length;i++){ + const pos = child.skeleton.bones[i].position; + child.skeleton.bones[i].userData.vrm0RestPosition = { x:pos.x, y:pos.y, z:pos.z} + } + } + //if (vrm.meta?.metaVersion === '0') child.userData.isVRM0 = true; + } } }) diff --git a/src/library/merge-geometry.js b/src/library/merge-geometry.js index 91651960..e2a156d5 100644 --- a/src/library/merge-geometry.js +++ b/src/library/merge-geometry.js @@ -31,6 +31,28 @@ export function cloneSkeleton(skinnedMesh) { return newSkeleton; } +function changeBoneHandedness(bone) { + console.log("isvrm0") + // Clone the bone and apply handedness change + const clone = bone.clone(false); + + // Reverse the X-axis scale to change handedness + const scale = clone.scale; + scale.x = -scale.x; + + // Reverse the rotation around the Y-axis to change handedness + const rotation = clone.rotation; + rotation.y = -rotation.y; + + // You might need to adjust the position as well depending on your specific use case. + // If the mesh is centered at the origin, this may not be necessary. + // If your mesh has been moved from the origin, you may need to adjust the position as well. + // clone.position.x = -clone.position.x; + + clone.position.set(0,0,0); + + return clone; +} function createMergedSkeleton(meshes, scale){ /* user should be careful with naming convetions in custom bone names out from humanoids vrm definition, for example ones that come from head (to add hair movement), should start with vrm's connected bone @@ -42,6 +64,7 @@ function createMergedSkeleton(meshes, scale){ let index = 0; meshes.forEach(mesh => { if (mesh.skeleton){ + const nonduparr = getOrderedNonDupArray(mesh.geometry.attributes.skinIndex.array); const boneArr = [] nonduparr.forEach(index => { @@ -62,13 +85,13 @@ function createMergedSkeleton(meshes, scale){ mesh.skeleton.bones.forEach((bone, boneInd) => { // only bones that are included in the previous array (used bones) if (boneArr.indexOf(bone)!==-1){ - const clone = boneClones.get(bone.name) + const clone = boneClones.get(bone.name); if (clone == null){ // no clone was found with the bone const boneData = { index, boneInverses:mesh.skeleton.boneInverses[boneInd], - bone: bone.clone(false), - parentName: bone.parent?.type == "Bone" ? bone.parent.name:null + bone: bone.clone(false), + parentName: bone.parent?.type == "Bone" ? bone.parent.name:null, } index++ boneClones.set(bone.name, boneData); @@ -94,6 +117,16 @@ function createMergedSkeleton(meshes, scale){ newSkeleton.pose(); newSkeleton.bones.forEach(bn => { + const vrm0RestPosition = bn.userData?.restPosition; + if (vrm0RestPosition){ + // Adjust position + if (restPosition){ + bn.position.set(-vrm0RestPosition.x, vrm0RestPosition.y, -vrm0RestPosition.z); + } + + // Adjust rotation to change handedness + //bn.rotation.set(bn.rotation.x, -bn.rotation.y, -bn.rotation.z); + } bn.position.set(bn.position.x *scale, bn.position.y*scale,bn.position.z*scale); }); return newSkeleton @@ -569,11 +602,20 @@ function mergeSourceIndices({ meshes }) { // function remapAnimationClips({ animationClips, sourceMorphTargetDictionaries, meshes, destMorphTargetDictionary }) { // return animationClips.map((clip) => new THREE.AnimationClip(clip.name, clip.duration, clip.tracks.map((track) => remapKeyframeTrack({ track, sourceMorphTargetDictionaries, meshes, destMorphTargetDictionary })), clip.blendMode)); // } + + export function mergeGeometry({ meshes, scale }, isVrm0 = false) { // eslint-disable-next-line no-unused-vars let uvcount = 0; meshes.forEach(mesh => { uvcount += mesh.geometry.attributes.uv.count; + + if (mesh.userData?.isVRM0){ + for (let i = 0; i < mesh.geometry.attributes.position.array.length; i+=3){ + mesh.geometry.attributes.position.array[i] *= -1 + mesh.geometry.attributes.position.array[i+2] *= -1 + } + } }); const source = { meshes, From aab70a0b8585f11865ca84c0456db07c15f605c1 Mon Sep 17 00:00:00 2001 From: memelotsqui Date: Sat, 28 Oct 2023 02:22:06 -0600 Subject: [PATCH 2/4] reverse position when vrm0 format --- src/components/Selector.jsx | 10 +++++----- src/library/merge-geometry.js | 13 ++++--------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/components/Selector.jsx b/src/components/Selector.jsx index 0308ae68..3dcf5124 100644 --- a/src/components/Selector.jsx +++ b/src/components/Selector.jsx @@ -526,8 +526,9 @@ export default function Selector({confirmDialog, templateInfo, animationManager, let vrm = null models.map((m)=>{ + // basic vrm setup (only if model is vrm) vrm = m.userData.vrm; - + if (getAsArray(templateInfo.lipSyncTraits).indexOf(traitData.trait) !== -1) setLipSync(new LipSync(vrm)); renameVRMBones(vrm) @@ -621,11 +622,10 @@ export default function Selector({confirmDialog, templateInfo, animationManager, if (vrm.meta?.metaVersion === '0'){ VRMUtils.rotateVRM0( vrm ); for (let i =0; i < child.skeleton.bones.length;i++){ - const pos = child.skeleton.bones[i].position; - child.skeleton.bones[i].userData.vrm0RestPosition = { x:pos.x, y:pos.y, z:pos.z} - } + child.skeleton.bones[i].userData.vrm0RestPosition = { ... child.skeleton.bones[i].position } + } + child.userData.isVRM0 = true; } - //if (vrm.meta?.metaVersion === '0') child.userData.isVRM0 = true; } } }) diff --git a/src/library/merge-geometry.js b/src/library/merge-geometry.js index e2a156d5..da5d9af9 100644 --- a/src/library/merge-geometry.js +++ b/src/library/merge-geometry.js @@ -92,6 +92,7 @@ function createMergedSkeleton(meshes, scale){ boneInverses:mesh.skeleton.boneInverses[boneInd], bone: bone.clone(false), parentName: bone.parent?.type == "Bone" ? bone.parent.name:null, + } index++ boneClones.set(bone.name, boneData); @@ -117,15 +118,9 @@ function createMergedSkeleton(meshes, scale){ newSkeleton.pose(); newSkeleton.bones.forEach(bn => { - const vrm0RestPosition = bn.userData?.restPosition; - if (vrm0RestPosition){ - // Adjust position - if (restPosition){ - bn.position.set(-vrm0RestPosition.x, vrm0RestPosition.y, -vrm0RestPosition.z); - } - - // Adjust rotation to change handedness - //bn.rotation.set(bn.rotation.x, -bn.rotation.y, -bn.rotation.z); + const restPosition = bn.userData?.vrm0RestPosition; + if (restPosition){ + bn.position.set(-restPosition.x, restPosition.y, -restPosition.z); } bn.position.set(bn.position.x *scale, bn.position.y*scale,bn.position.z*scale); }); From 365f23c6a4f81cea4133493fd2de28b2d0991c24 Mon Sep 17 00:00:00 2001 From: memelotsqui Date: Sat, 28 Oct 2023 02:53:19 -0600 Subject: [PATCH 3/4] set mouselook to false by default --- src/components/TraitInformation.jsx | 2 +- src/library/animationManager.js | 3 +-- src/library/lookatManager.js | 9 +++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/TraitInformation.jsx b/src/components/TraitInformation.jsx index cd190f51..131b06ce 100644 --- a/src/components/TraitInformation.jsx +++ b/src/components/TraitInformation.jsx @@ -15,7 +15,7 @@ export default function TraitInformation({currentVRM, animationManager, lookatMa const [cullInDistance, setCullInDistance] = useState(0); const [cullLayer, setCullLayer] = useState(0); const [animationName, setAnimationName] = useState(animationManager.getCurrentAnimationName()); - const [hasMouseLook, setHasMouseLook] = useState(lookatManager.enabled); + const [hasMouseLook, setHasMouseLook] = useState(lookatManager.userActivated); useEffect(() => { if (currentVRM != null){ diff --git a/src/library/animationManager.js b/src/library/animationManager.js index 3084b992..71bec960 100644 --- a/src/library/animationManager.js +++ b/src/library/animationManager.js @@ -21,7 +21,6 @@ class AnimationControl { this.to = null; this.from = null; this.vrm = vrm; - this.animationManager = null; this.animationManager = animationManager; this.mixamoModel = null; @@ -159,7 +158,7 @@ export class AnimationManager{ this.curAnimID = 0; this.animationControls = []; this.started = false; - this.mouseLookEnabled = true; + this.mouseLookEnabled = false; this.mixamoModel = null; this.mixamoAnimations = null; diff --git a/src/library/lookatManager.js b/src/library/lookatManager.js index 4dfdde30..61a06698 100644 --- a/src/library/lookatManager.js +++ b/src/library/lookatManager.js @@ -9,10 +9,10 @@ export class LookAtManager { this.leftEyeBones = [] this.rightEyesBones = [] this.curMousePos = new THREE.Vector2() - this.enabled = true; this.hotzoneSection = getHotzoneSection() - this.enabled = true + this.enabled = false; + this.userActivated = false; this.lookInterest = 1 this.hasInterest = true this.interestSpeed = 0.3 @@ -58,7 +58,8 @@ export class LookAtManager { // }, 1000/60); } setActive(active){ - this.enabled = active; + console.log("is activating") + this.userActivated = active; } setCamera(camera){ this.camera = camera @@ -131,7 +132,7 @@ export class LookAtManager { const cameraRotationThreshold = localVector.z > 0.; // if camera rotation is not larger than 90 if (this.curMousePos.x > this.hotzoneSection.xStart && this.curMousePos.x < this.hotzoneSection.xEnd && this.curMousePos.y > this.hotzoneSection.yStart && this.curMousePos.y < this.hotzoneSection.yEnd && - cameraRotationThreshold && this.enabled) { + cameraRotationThreshold && this.enabled && this.userActivated) { this.neckBones.forEach(neck => { this._moveJoint(neck, this.maxLookPercent.neck) }) From 883a8bee4b61b1f9f72e6e378b41091cd6f06cf4 Mon Sep 17 00:00:00 2001 From: memelotsqui Date: Sat, 28 Oct 2023 02:54:48 -0600 Subject: [PATCH 4/4] console added vrm0 file --- src/components/Selector.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Selector.jsx b/src/components/Selector.jsx index 3dcf5124..aecd0637 100644 --- a/src/components/Selector.jsx +++ b/src/components/Selector.jsx @@ -621,6 +621,7 @@ export default function Selector({confirmDialog, templateInfo, animationManager, createBoneDirection(child) if (vrm.meta?.metaVersion === '0'){ VRMUtils.rotateVRM0( vrm ); + console.log("Loaded VRM0 file ", vrm); for (let i =0; i < child.skeleton.bones.length;i++){ child.skeleton.bones[i].userData.vrm0RestPosition = { ... child.skeleton.bones[i].position } }