web mmd viewer
1.0.0
A sample project using three.js and the-world-engine
Through the-world-engine, you can build a scene of three.js in a declarative form.
Scripting is also possible through a the-world-engine messaging system - similar to the Unity
As a result, it becomes very intuitive to build a scene of three.js.
// src/asset/Bootstrapper.ts
export class Bootstrapper extends BaseBootstrapper {
public override run(): SceneBuilder {
//...
return this.sceneBuilder
//...
.withChild(instantiater.buildGameObject("orbit-camera", new THREE.Vector3(0, 0, 40))
.withComponent(Camera, c => {
c.cameraType = CameraType.Perspective;
c.fov = 60;
c.far = 1500;
c.priority = -1;
})
.withComponent(OrbitControls, c => {
c.enabled = true;
c.target = new THREE.Vector3(0, 14, 0);
c.minDistance = 20;
c.maxDistance = 100;
c.enableDamping = false;
})
.getComponent(Camera, orbitCamera))
.withChild(instantiater.buildGameObject("ambient-light")
.withComponent(Object3DContainer, c => c.object3D = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.3)))
.withChild(instantiater.buildGameObject("directional-light", new THREE.Vector3(-20, 30, 100))
.withComponent(Object3DContainer, c => {
const light = new THREE.DirectionalLight(0xffffff, 0.5);
//...
c.object3D = light;
})
.getComponent(Object3DContainer, directionalLight))
.withChild(instantiater.buildGameObject("polar-grid-helper")
.active(false)
.withComponent(Object3DContainer, c => c.object3D = new THREE.GridHelper(30, 10)))
//...
.withChild(instantiater.buildGameObject("mmd-model")
.withComponent(Object3DContainer, c => {
c.startCoroutine(loadAndRun());
function *loadAndRun(): CoroutineIterator {
//...
const loader = new MMDLoader();
let model: THREE.SkinnedMesh<THREE.BufferGeometry, THREE.Material | THREE.Material[]>|null = null;
loader.load(modelFile, object => model = object, makeProgressUpdate("model", modelLoadingText));
yield new WaitUntil(() => model !== null);
modelLoadingText.innerText = "model loaded";
c.object3D = model;
const threeCamera = DuckThreeCamera.createInterface(camera.ref!, false).toThreeCamera();
let modelAnimation: THREE.AnimationClip|null = null;
loader.loadAnimation(vmdFiles as any, model!,
object => modelAnimation = object as THREE.AnimationClip, makeProgressUpdate("model animation", modelAnimationLoadingText));
yield new WaitUntil(() => modelAnimation !== null);
modelAnimationLoadingText.innerText = "model animation loaded";
let cameraAnimation: THREE.AnimationClip|null = null;
loader.loadAnimation(cameraFile, threeCamera,
object => cameraAnimation = object as THREE.AnimationClip, makeProgressUpdate("camera motion", cameraLoadingText));
yield new WaitUntil(() => cameraAnimation !== null);
cameraLoadingText.innerText = "camera loaded";
const helper = new MMDAnimationHelper()
.enable("physics", vmdFiles.length < 2)
.enable("cameraAnimation", true)
.add(model!, { animation: modelAnimation! })
.add(threeCamera, { animation: cameraAnimation! });
loadingText.remove();
yield null;
for (; ;) {
helper.update(c.engine.time.deltaTime);
c.updateWorldMatrix();
yield null;
}
}
}))
;
}
}
credit:
credit:
credit: