fix
This commit is contained in:
parent
40f6d6b8c4
commit
6aa33c1178
40
.github/workflows/gh-pages.yml
vendored
Normal file
40
.github/workflows/gh-pages.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
name: github pages
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
env:
|
||||||
|
GITEA_MAIL: ${{ secrets.GITEA_MAIL }}
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
ref: main
|
||||||
|
submodules: true
|
||||||
|
fetch-depth: 0
|
||||||
|
- run: |
|
||||||
|
yarn install
|
||||||
|
rm -rf dist/vrma
|
||||||
|
git clone https://${GITEA_TOKEN}@git.syui.ai/ai/vrma dist/vrma
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
env:
|
||||||
|
TZ: "Asia/Tokyo"
|
||||||
|
run: |
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
uses: peaceiris/actions-gh-pages@v3
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
publish_dir: ./dist
|
||||||
|
user_name: 'ai[bot]'
|
||||||
|
user_email: '138105980+yui-syui-ai[bot]@users.noreply.github.com'
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
node_modules
|
||||||
|
package-lock.json
|
||||||
|
example
|
||||||
|
yarn.lock
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "dist/vrma"]
|
||||||
|
path = dist/vrma
|
||||||
|
url = git@git.syui.ai:ai/vrma
|
22
README.md
22
README.md
@ -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
|
||||||
```
|
```
|
||||||
|
|
||||||
|
1
dist/CNAME
vendored
Normal file
1
dist/CNAME
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
v.syui.ai
|
8
dist/index.html
vendored
Normal file
8
dist/index.html
vendored
Normal 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
156
dist/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/vrma
vendored
Submodule
1
dist/vrma
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 3e83eb3efde28bcc4665c63ad6f0c02b849619e3
|
22
package.json
Normal file
22
package.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"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",
|
||||||
|
"@pixiv/three-vrm-springbone": "^2.1.1",
|
||||||
|
"three": "^0.162.0"
|
||||||
|
}
|
||||||
|
}
|
211
src/index.ts
Normal file
211
src/index.ts
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
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';
|
||||||
|
|
||||||
|
import { VRMSpringBoneManager, VRMSpringBoneJoint, VRMSpringBoneJointHelper } from '@pixiv/three-vrm-springbone';
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
// https://threejs.org/docs/#api/en/constants/Renderer
|
||||||
|
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.ReinhardToneMapping;
|
||||||
|
renderer.toneMapping = THREE.NeutralToneMapping;
|
||||||
|
canvas.appendChild(renderer.domElement);
|
||||||
|
renderer.toneMappingExposure = 1.5;
|
||||||
|
|
||||||
|
//renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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;
|
||||||
|
floor.name = "floor";
|
||||||
|
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();
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
controls.update();
|
||||||
|
const delta = clock.getDelta();
|
||||||
|
if (currentMixer) {
|
||||||
|
currentMixer.update(delta);
|
||||||
|
}
|
||||||
|
if (currentVrm) {
|
||||||
|
currentVrm.update(delta);
|
||||||
|
}
|
||||||
|
requestAnimationFrame(animate);
|
||||||
|
scene.rotation.y += 0.005;
|
||||||
|
renderer.render(scene, camera);
|
||||||
|
}
|
||||||
|
animate();
|
||||||
|
|
||||||
|
function random_happy() {
|
||||||
|
// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/expressions.ja.md
|
||||||
|
currentVrm.expressionManager.setValue('relaxed', 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function random_head() {
|
||||||
|
// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/lookAt.ja.md
|
||||||
|
currentVrm.lookAt.target = camera;
|
||||||
|
currentVrm.VRMLookAtBoneApplier = camera;
|
||||||
|
currentVrm.VRMLookAtExpressionApplier = camera;
|
||||||
|
|
||||||
|
// https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/humanoid.ja.md
|
||||||
|
const head = currentVrm.humanoid.getRawBoneNode("head");
|
||||||
|
head.target = camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
function random_blink(){
|
||||||
|
setInterval(() => {
|
||||||
|
currentVrm.expressionManager.setValue('relaxed', 0);
|
||||||
|
currentVrm.expressionManager.setValue('blink', 0);
|
||||||
|
random_head();
|
||||||
|
const r = Math.floor(Math.random() * 3);
|
||||||
|
if (r == 1) {
|
||||||
|
setTimeout(() => { currentVrm.expressionManager.setValue('blink', 1); }, 5000);
|
||||||
|
setTimeout(() => {
|
||||||
|
currentVrm.expressionManager.setValue('blink', 0);
|
||||||
|
}, 5500);
|
||||||
|
};
|
||||||
|
setTimeout(() => {
|
||||||
|
currentVrm.expressionManager.setValue('relaxed', 0.5);
|
||||||
|
currentVrm.expressionManager.setValue('blink', 1);
|
||||||
|
}, 6000);
|
||||||
|
}, 6500);
|
||||||
|
}
|
||||||
|
random_blink();
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
const r = Math.floor(Math.random() * 4 + 1);
|
||||||
|
load("/vrma/" + r + ".vrma");
|
||||||
|
setTimeout(() => {
|
||||||
|
load("/vrma/fly_c.vrma");
|
||||||
|
}, 10000);
|
||||||
|
}, 15000);
|
||||||
|
|
||||||
|
function light_off(){
|
||||||
|
renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
||||||
|
light.intensity = -0.5;
|
||||||
|
scene.background = new THREE.Color(0x000000);
|
||||||
|
scene.fog = new Fog(0x000000, 3, 20);
|
||||||
|
}
|
||||||
|
//light_off();
|
||||||
|
})
|
7
tsconfig.json
Normal file
7
tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2016",
|
||||||
|
"module": "commonjs",
|
||||||
|
"skipLibCheck": true
|
||||||
|
}
|
||||||
|
}
|
26
webpack.config.js
Normal file
26
webpack.config.js
Normal 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"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user