1
0
This commit is contained in:
syui 2024-03-18 19:59:59 +09:00
parent 40f6d6b8c4
commit d7d3542277
Signed by: syui
GPG Key ID: 5417CFEBAD92DF56
10 changed files with 407 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
package-lock.json

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "dist/vrma"]
path = dist/vrma
url = git@git.syui.ai:ai/vrma

View File

@ -1,6 +1,28 @@
# vrm
## vrm & vrma
```sh
$ git submodule update --init --recursive
```
or
- vrm : [download](https://hub.vroid.com/characters/675572020956181239/models/7175071267176594918)
- vrma : [download](https://vroid.booth.pm/items/5512385)
> ./dist/vrma
```js
load("/vrma/model.vrm");
load("/vrma/VRMA_01.vrma");
```
## build
```sh ```sh
$ npm i $ npm i
$ npm run dev $ npm run dev
$ npm run build $ npm run build
``` ```

8
dist/index.html vendored Normal file
View File

@ -0,0 +1,8 @@
<html>
<head>
<script src="main.js"></script>
</head>
<body>
<div id="canvas" style="width:100%;height:640px;"></div>
</body>
</html>

156
dist/main.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/vrma vendored Submodule

@ -0,0 +1 @@
Subproject commit 3e83eb3efde28bcc4665c63ad6f0c02b849619e3

21
package.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "vrm",
"version": "0.0.1",
"private": true,
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server --open"
},
"devDependencies": {
"ts-loader": "^9.5.1",
"typescript": "^5.4.2",
"webpack": "^5.90.3",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.3"
},
"dependencies": {
"@pixiv/three-vrm": "^2.1.1",
"@pixiv/three-vrm-animation": "^2.1.1",
"three": "^0.162.0"
}
}

161
src/index.ts Normal file
View File

@ -0,0 +1,161 @@
import * as THREE from "three"
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { VRMLoaderPlugin } from "@pixiv/three-vrm";
import { createVRMAnimationClip, VRMAnimationLoaderPlugin } from "@pixiv/three-vrm-animation";
import { Color, DirectionalLight, Fog, HemisphereLight } from 'three';
import { GridHelper, Mesh, MeshLambertMaterial, BoxGeometry, Vector3 } from 'three';
window.addEventListener("DOMContentLoaded", () => {
const canvas = document.getElementById("canvas");
if (canvas == null) return;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
30, canvas.clientWidth/canvas.clientHeight, 0.1, 20);
camera.position.set(0.0, 0.9, -4.0)
camera.rotation.set(0.0, Math.PI, 0.0)
camera.lookAt(new THREE.Vector3(0, 0, 0));
const renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(canvas.clientWidth, canvas.clientHeight);
renderer.setClearColor(0x7fbfff, 1.0);
renderer.shadowMap.enabled = true;
renderer.outputColorSpace = THREE.SRGBColorSpace;
//renderer.toneMapping = THREE.ACESFilmicToneMapping;
//renderer.toneMappingExposure = 1;
canvas.appendChild(renderer.domElement);
const light = new THREE.DirectionalLight(0xffffff, Math.PI);
light.position.set(1.0, 1.0, 1.0);
scene.add(light);
let currentVrm: any = undefined;
let currentVrmAnimation: any = undefined;
let currentMixer:any = undefined;
function load(url: string) {
loader.load(
url,
(gltf) => {
tryInitVRM(gltf);
tryInitVRMA(gltf);
},
(progress) => console.log(
"Loading model...",
100.0 * (progress.loaded / progress.total), "%"
),
(error) => console.error(error)
);
}
function tryInitVRM(gltf: any) {
const vrm = gltf.userData.vrm;
if ( vrm == null ) {
return;
}
currentVrm = vrm;
scene.add(vrm.scene);
initAnimationClip();
}
function tryInitVRMA(gltf: any) {
const vrmAnimations = gltf.userData.vrmAnimations;
if (vrmAnimations == null) {
return;
}
currentVrmAnimation = vrmAnimations[0] ?? null;
initAnimationClip();
}
function initAnimationClip() {
if (currentVrm && currentVrmAnimation) {
currentMixer = new THREE.AnimationMixer(currentVrm.scene);
const clip = createVRMAnimationClip(currentVrmAnimation, currentVrm);
currentMixer.clipAction(clip).play();
}
}
const loader = new GLTFLoader();
loader.register((parser) => {
return new VRMLoaderPlugin(parser);
});
loader.register((parser) => {
return new VRMAnimationLoaderPlugin(parser);
});
load("/vrma/ai.vrm");
load("/vrma/fly_c.vrma");
const clock = new THREE.Clock();
clock.start();
const update = () => {
controls.update();
requestAnimationFrame(update);
const deltaTime = clock.getDelta();
if (currentMixer) {
currentMixer.update(deltaTime);
}
if (currentVrm) {
currentVrm.update(deltaTime);
}
renderer.render(scene, camera);
}
scene.background = new THREE.Color( 0xffffff );
const directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
const ambientLight = new THREE.AmbientLight(0x333333);
scene.add(ambientLight);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.2;
controls.enableRotate = true;
controls.target.set( 0.0, 1.0, 0.0 );
function floor_default(){
const floor = new Mesh(
new BoxGeometry(50, 100),
new MeshLambertMaterial({
color: 0xffffff,
depthWrite: true,
})
);
floor.position.y = -1.0;
floor.rotation.x = -Math.PI / 2;
scene.add(floor);
}
function floor_grid(){
const grid = new GridHelper(50, 100, 0xffffff, 0xffffff);
scene.add(grid);
grid.position.set(Math.round(0), 0, Math.round(0));
}
function floor_bg(){
scene.fog = new Fog(0xffffff, 3, 20);
scene.fog?.color.set(0xffffff);
}
floor_default();
floor_grid();
floor_bg();
update();
setInterval(() => {
const r = Math.floor(Math.random() * 4 + 1);
load("/vrma/" + r + ".vrma");
setTimeout(() => {
load("/vrma/fly_c.vrma");
}, 10000);
}, 15000);
})

7
tsconfig.json Normal file
View File

@ -0,0 +1,7 @@
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"skipLibCheck": true
}
}

26
webpack.config.js Normal file
View File

@ -0,0 +1,26 @@
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.ts',
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader'
}
]
},
resolve: {
extensions: ['.ts', '.js']
},
output: {
filename: 'main.js',
path: path.join(__dirname, "dist")
},
devServer: {
static: {
directory: path.join(__dirname, "dist"),
}
}
}