Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
},
"dependencies": {
"@moeru/three-mmd": "workspace:^",
"@moeru/three-mmd-physics-ammo": "workspace:^",
"@moeru/three-mmd-physics-springbone": "workspace:^",
"@moeru/three-mmd-r3f": "workspace:^",
"@react-three/drei": "catalog:r3f",
"@react-three/fiber": "catalog:r3f",
Expand Down
7 changes: 4 additions & 3 deletions examples/playground/src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Ammo } from '@moeru/three-mmd-r3f'
import { initAmmo } from '@moeru/three-mmd-physics-ammo'
import { SetupPhysics } from '@moeru/three-mmd-r3f'
import { Environment, Loader, OrbitControls, Stats } from '@react-three/drei'
import { Canvas } from '@react-three/fiber'
import { Suspense } from 'react'
Expand All @@ -13,12 +14,12 @@ const App = () => (
style={{ height: '100dvh', touchAction: 'none', width: '100dvw' }}
>
<Suspense fallback={null}>
<Ammo>
<SetupPhysics setup={initAmmo}>
<Outlet />
<OrbitControls />
<directionalLight intensity={1.64} position={[2.1, 0, 24]} rotation={[0, 2 * Math.PI, 0]} />
<Environment background files="https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/2k/belfast_sunset_puresky_2k.hdr" />
</Ammo>
</SetupPhysics>
</Suspense>
</Canvas>
</>
Expand Down
28 changes: 6 additions & 22 deletions examples/playground/src/pages/debug/ammo.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import type { MMDPhysicsHelper } from 'three-stdlib'

import { buildAnimation, MMDAmmoPhysics, MMDLoader, VMDLoader } from '@moeru/three-mmd'
import { useMMDAnimations } from '@moeru/three-mmd-r3f'
import { useFrame, useLoader } from '@react-three/fiber'
import { MMDAmmoPhysics } from '@moeru/three-mmd-physics-ammo'
import { useMMD, useMMDAnimation, useMMDAnimations, useMMDPhysics } from '@moeru/three-mmd-r3f'
import { useControls } from 'leva'
import { useEffect, useMemo, useState } from 'react'

Expand Down Expand Up @@ -38,20 +35,14 @@ const DebugAmmo = () => {
showSkeleton: false,
})

const mmd = useLoader(MMDLoader, pmxUrl, loader => loader.register(MMDAmmoPhysics))
const vmd = useLoader(VMDLoader, vmdUrl)

const animation = useMemo(() => {
const animation = buildAnimation(vmd, mmd.mesh)
animation.name = 'dance'
return animation
}, [vmd, mmd])
const mmd = useMMD(pmxUrl)
const animation = useMMDAnimation(vmdUrl, mmd.mesh, 'dance')

const { actions, ikSolver } = useMMDAnimations([animation], mmd.mesh, mmd.iks, mmd.grants)

// Helpers
const ikHelper = useMemo(() => ikSolver.createHelper(), [ikSolver])
const physicsHelper = useMemo(() => mmd.createPhysicsHelpers(), [mmd])
const physicsHelper = useMMDPhysics(mmd, MMDAmmoPhysics)

// Play the animation on mount
useEffect(() => {
Expand Down Expand Up @@ -83,13 +74,6 @@ const DebugAmmo = () => {
}
}, [actions, mmd, editingScale])

useFrame((_, delta) => {
if (editingScale)
return

mmd.update(delta)
})

return (
<>
<primitive
Expand All @@ -98,7 +82,7 @@ const DebugAmmo = () => {
/>
{showIK && <primitive object={ikHelper} />}
{showSkeleton && <skeletonHelper args={[mmd.mesh]} />}
{showPhysics && (Boolean(physicsHelper)) && <primitive object={physicsHelper as MMDPhysicsHelper} />}
{showPhysics && (Boolean(physicsHelper)) && <primitive object={physicsHelper} />}
</>

)
Expand Down
7 changes: 3 additions & 4 deletions examples/playground/src/pages/debug/refactor-test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { SpringBoneHelpers } from '@moeru/three-mmd'

import { buildAnimation, MMDLoader, VMDLoader } from '@moeru/three-mmd'
import { useMMDAnimations } from '@moeru/three-mmd-r3f'
import { MMDSpringBonePhysics } from '@moeru/three-mmd-physics-springbone'
import { useMMDAnimations, useMMDPhysics } from '@moeru/three-mmd-r3f'
import { useFrame, useLoader } from '@react-three/fiber'
import { useControls } from 'leva'
import { useEffect, useMemo, useState } from 'react'
Expand Down Expand Up @@ -53,7 +52,7 @@ const DebugRefactorTest = () => {

// Helpers
const ikHelper = useMemo(() => ikSolver.createHelper(), [ikSolver])
const { colliderHelpers, jointHelpers } = useMemo(() => mmd.createPhysicsHelpers() as SpringBoneHelpers, [mmd])
const { colliderHelpers, jointHelpers } = useMMDPhysics(mmd, MMDSpringBonePhysics)

// Play the animation on mount
useEffect(() => {
Expand Down
50 changes: 50 additions & 0 deletions packages/three-mmd-physics-ammo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "@moeru/three-mmd-physics-ammo",
"type": "module",
"version": "0.0.5",
"private": true,
"description": "Use MMD on Three.js",
"author": "Moeru AI",
"license": "MIT",
"homepage": "https://github.com/moeru-ai/three-mmd",
"repository": {
"type": "git",
"url": "git+https://github.com/moeru-ai/three-mmd.git",
"directory": "packages/three-mmd-physics-ammo"
},
"bugs": "https://github.com/moeru-ai/three-mmd/issues",
"keywords": [
"threejs",
"three",
"mmd"
],
"exports": "./src/index.ts",
"files": [
"dist"
],
"publishConfig": {
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"scripts": {
"build": "pkgroll"
},
"peerDependencies": {
"@moeru/three-mmd": "workspace:^",
"@types/three": "^0.180.0",
"three": "^0.180.0"
},
"devDependencies": {
"@moeru/three-mmd": "workspace:^",
"@types/three": "catalog:",
"ammojs-typed": "catalog:",
"three": "catalog:"
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable new-cap */
import type { PmxObject } from 'babylon-mmd/esm/Loader/Parser/pmxObject'
import type { PmxObject } from '@moeru/three-mmd'
import type { SkinnedMesh } from 'three'

import Ammo from 'ammojs-typed'
Expand Down
22 changes: 22 additions & 0 deletions packages/three-mmd-physics-ammo/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { PhysicsFactory } from '@moeru/three-mmd'

import type { MMDPhysicsHelper } from './mmd-physics-helper'

import { MMDPhysics } from './mmd-physics'

export const MMDAmmoPhysics: PhysicsFactory<MMDPhysicsHelper> = (mmd) => {
const physics = new MMDPhysics(
mmd.mesh,
mmd.pmx.rigidBodies,
mmd.pmx.joints,
)

// physics.warmup(60)

return {
createHelper: () => physics.createHelper(),
update: (delta: number) => physics.update(delta),
}
}

export { initAmmo } from './init'
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { SkinnedMesh } from 'three'

import { PmxObject } from 'babylon-mmd/esm/Loader/Parser/pmxObject'
import { PmxObject } from '@moeru/three-mmd'
import {
BoxGeometry,
CapsuleGeometry,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable new-cap */
import type { PmxObject } from 'babylon-mmd/esm/Loader/Parser/pmxObject'
import type { PmxObject } from '@moeru/three-mmd'
import type { SkinnedMesh } from 'three'

import Ammo from 'ammojs-typed'
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* eslint-disable new-cap */
import type { SkinnedMesh } from 'three'

import { PmxObject } from '@moeru/three-mmd'
import Ammo from 'ammojs-typed'
import { PmxObject } from 'babylon-mmd/esm/Loader/Parser/pmxObject'
import { Bone, Euler, Quaternion, Vector3 } from 'three'

import type { ResourceManager } from './resource-manager'
Expand Down Expand Up @@ -157,7 +157,7 @@
this.body.getMotionState().getWorldTransform(tr)
manager.copyOrigin(tr, form)

// TODO: check the most appropriate way to set

Check warning on line 160 in packages/three-mmd-physics-ammo/src/rigid-body.ts

View workflow job for this annotation

GitHub Actions / check

Complete the task associated to this "TODO" comment
// this.body.setWorldTransform( tr );
this.body.setCenterOfMassTransform(tr)
this.body.getMotionState().setWorldTransform(tr)
Expand All @@ -170,7 +170,7 @@
const manager = this.manager
const form = this._getBoneTransform()

// TODO: check the most appropriate way to set

Check warning on line 173 in packages/three-mmd-physics-ammo/src/rigid-body.ts

View workflow job for this annotation

GitHub Actions / check

Complete the task associated to this "TODO" comment
// this.body.setWorldTransform( form );
this.body.setCenterOfMassTransform(form)
this.body.getMotionState().setWorldTransform(form)
Expand Down
52 changes: 52 additions & 0 deletions packages/three-mmd-physics-springbone/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "@moeru/three-mmd-physics-springbone",
"type": "module",
"version": "0.0.5",
"private": true,
"description": "Use MMD on Three.js",
"author": "Moeru AI",
"license": "MIT",
"homepage": "https://github.com/moeru-ai/three-mmd",
"repository": {
"type": "git",
"url": "git+https://github.com/moeru-ai/three-mmd.git",
"directory": "packages/three-mmd-physics-springbone"
},
"bugs": "https://github.com/moeru-ai/three-mmd/issues",
"keywords": [
"threejs",
"three",
"mmd"
],
"exports": "./src/index.ts",
"files": [
"dist"
],
"publishConfig": {
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"scripts": {
"build": "pkgroll"
},
"peerDependencies": {
"@moeru/three-mmd": "workspace:^",
"@types/three": "^0.180.0",
"three": "^0.180.0"
},
"dependencies": {
"@pixiv/three-vrm-springbone": "catalog:"
},
"devDependencies": {
"@moeru/three-mmd": "workspace:^",
"@types/three": "catalog:",
"three": "catalog:"
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { PhysicsFactory } from '@moeru/three-mmd'
/**
* Spring bone physics strategy (functional): builds colliders/joints once from PMX + mesh,
* powered by @pixiv/three-vrm-springbone. Exposes a PhysicsStrategy for plugging into MMD.
*/
import type { Bone } from 'three'

import { PmxObject } from '@moeru/three-mmd'
import {
VRMSpringBoneCollider,
VRMSpringBoneColliderHelper,
Expand All @@ -13,17 +15,14 @@ import {
VRMSpringBoneJointHelper,
VRMSpringBoneManager,
} from '@pixiv/three-vrm-springbone'
import { PmxObject } from 'babylon-mmd/esm/Loader/Parser/pmxObject'
import { Vector3 } from 'three'

import type { BuildPhysicsOptions, PhysicsStrategy } from '../utils/build-physics'

export interface SpringBoneHelpers {
colliderHelpers: VRMSpringBoneColliderHelper[]
jointHelpers: VRMSpringBoneJointHelper[]
}

export const createSpringBonePhysics = (opts: BuildPhysicsOptions): PhysicsStrategy<SpringBoneHelpers> => {
export const MMDSpringBonePhysics: PhysicsFactory<SpringBoneHelpers> = (mmd) => {
let manager = new VRMSpringBoneManager()
const colliders: VRMSpringBoneCollider[] = []
const joints: VRMSpringBoneJoint[] = []
Expand Down Expand Up @@ -61,8 +60,7 @@ export const createSpringBonePhysics = (opts: BuildPhysicsOptions): PhysicsStrat

// Initialize hair joints based on bone names
const setupHairJoints = () => {
const { bones } = opts.mesh.skeleton
bones
mmd.mesh.skeleton.bones
.filter(bone => ['髪', 'Hair', 'Twin'].some(v => bone.name.includes(v)))
.forEach(bone => bone.children.forEach((child) => {
joints.push(
Expand All @@ -76,7 +74,7 @@ export const createSpringBonePhysics = (opts: BuildPhysicsOptions): PhysicsStrat

// Initialize skirt joints based on bone names
const setupSkirtJoints = () => {
opts.mesh.skeleton.bones
mmd.mesh.skeleton.bones
.filter(bone => ['裙', 'スカート', 'Skirt'].some(v => bone.name.includes(v)))
.forEach(bone => bone.children.forEach((child) => {
const joint = new VRMSpringBoneJoint(bone, child, {
Expand All @@ -91,15 +89,15 @@ export const createSpringBonePhysics = (opts: BuildPhysicsOptions): PhysicsStrat
}

const setupColliders = () => {
const bones = opts.mesh.skeleton.bones
opts.mesh.updateMatrixWorld(true)
const bones = mmd.mesh.skeleton.bones
mmd.mesh.updateMatrixWorld(true)

const legBones = bones
.map((bone, idx) => ({ bone, idx }))
.filter(({ bone }) => ['センター', '上半身', '右ひざ', '右足', '右足D', '左ひざ', '左足', '左足D'].includes(bone.name))
// Map leg bones to their rigid bodies
const legRigidBodiesMap = new Map<number, PmxObject.RigidBody[]>()
opts.pmx.rigidBodies.forEach((rb) => {
mmd.pmx.rigidBodies.forEach((rb) => {
const list = legRigidBodiesMap.get(rb.boneIndex) ?? []
list.push(rb)
legRigidBodiesMap.set(rb.boneIndex, list)
Expand Down Expand Up @@ -130,7 +128,7 @@ export const createSpringBonePhysics = (opts: BuildPhysicsOptions): PhysicsStrat
rb.shapePosition[0],
rb.shapePosition[1],
rb.shapePosition[2],
]).applyMatrix4(opts.mesh.matrixWorld)
]).applyMatrix4(mmd.mesh.matrixWorld)
const offsetLocal = bone.worldToLocal(offsetWorld.clone())
// Create collider shape sphere
if (rb.shapeType === PmxObject.RigidBody.ShapeType.Sphere) {
Expand Down Expand Up @@ -175,7 +173,7 @@ export const createSpringBonePhysics = (opts: BuildPhysicsOptions): PhysicsStrat
setupHairJoints()
setupSkirtJoints()
joints.forEach(j => manager.addJoint(j))
opts.mesh.updateMatrixWorld(true)
mmd.mesh.updateMatrixWorld(true)
manager.setInitState()
cacheJointsAndColliders()

Expand All @@ -193,8 +191,6 @@ export const createSpringBonePhysics = (opts: BuildPhysicsOptions): PhysicsStrat
baseJointSizes.clear()
},

name: 'spring-bone',

setScalar: (scale?: number) => {
if (scale === undefined)
return
Expand Down Expand Up @@ -225,9 +221,9 @@ export const createSpringBonePhysics = (opts: BuildPhysicsOptions): PhysicsStrat
}
})

opts.mesh.updateMatrixWorld(true)
opts.mesh.skeleton.pose()
opts.mesh.updateMatrixWorld(true)
mmd.mesh.updateMatrixWorld(true)
mmd.mesh.skeleton.pose()
mmd.mesh.updateMatrixWorld(true)
manager.setInitState()
},

Expand Down
14 changes: 0 additions & 14 deletions packages/three-mmd-r3f/src/components/ammo.tsx

This file was deleted.

Loading
Loading