@@ -11,14 +11,19 @@ import {
11
11
} from "@pixiv/three-vrm-animation" ;
12
12
import { AnimationMixer , LoopOnce , LoopRepeat } from "three" ;
13
13
14
+ const animations = [
15
+ { url : "https://cdn.mikn.dev/vroid/shikanoko.vrma" , loop : true , percentage : 30 } ,
16
+ { url : "https://cdn.mikn.dev/vroid/hi.vrma" , loop : false , percentage : 70 } ,
17
+ ] ;
18
+
14
19
export const VRMModel : React . FC < {
15
20
vrm : import ( "@pixiv/three-vrm" ) . VRM | null ;
16
21
mixer : AnimationMixer | null ;
17
22
} > = ( { vrm, mixer } ) => {
18
23
useFrame ( ( { clock } , delta ) => {
19
24
if ( vrm ) {
20
- vrm . scene . position . set ( 0 , - 4 , 0 ) ;
21
- vrm . scene . scale . set ( 5 , 5 , 5 ) ;
25
+ vrm . scene . position . set ( 0 , - 4.2 , 0 ) ;
26
+ vrm . scene . scale . set ( 6. 5, 5 , 5 ) ;
22
27
vrm . scene . rotation . y = Math . PI ;
23
28
vrm . expressionManager ?. setValue ( "neutral" , 1 ) ;
24
29
@@ -46,7 +51,7 @@ export function VRM() {
46
51
return new Promise < import ( "@pixiv/three-vrm" ) . VRM > (
47
52
( resolve , reject ) => {
48
53
loader . load (
49
- "https://cdn.mikn.dev/vroid/mikan.dev(web ).vrm" ,
54
+ "https://cdn.mikn.dev/vroid/mikan.dev(kyonyu ).vrm" ,
50
55
( gltf : GLTF ) => {
51
56
const loadedVrm = gltf . userData . vrm ;
52
57
setVrm ( loadedVrm ) ;
@@ -65,14 +70,22 @@ export function VRM() {
65
70
) ;
66
71
} ;
67
72
73
+ function pickAnimation ( ) {
74
+ const total = animations . reduce ( ( sum , anim ) => sum + anim . percentage , 0 ) ;
75
+ const rand = Math . random ( ) * total ;
76
+ let acc = 0 ;
77
+ for ( const anim of animations ) {
78
+ acc += anim . percentage ;
79
+ if ( rand < acc ) return anim ;
80
+ }
81
+ return animations [ 0 ] ; // fallback
82
+ }
83
+
68
84
const loadAnimation = ( loadedVrm : import ( "@pixiv/three-vrm" ) . VRM ) => {
69
- const animationUrl =
70
- Math . random ( ) < 0.3
71
- ? "https://cdn.mikn.dev/vroid/shikanoko.vrma"
72
- : "https://cdn.mikn.dev/vroid/hi.vrma" ;
85
+ const { url, loop } = pickAnimation ( ) ;
73
86
74
87
loader . load (
75
- animationUrl ,
88
+ url ,
76
89
( gltf : GLTF ) => {
77
90
const vrmAnimations = gltf . userData . vrmAnimations ;
78
91
if ( vrmAnimations && vrmAnimations . length > 0 ) {
@@ -81,37 +94,26 @@ export function VRM() {
81
94
vrmAnimations [ 0 ] ,
82
95
loadedVrm ,
83
96
) ;
84
- const animationMixer = new AnimationMixer (
85
- loadedVrm . scene ,
86
- ) ;
87
- const action =
88
- animationMixer . clipAction ( animationClip ) ;
97
+ const animationMixer = new AnimationMixer ( loadedVrm . scene ) ;
98
+ const action = animationMixer . clipAction ( animationClip ) ;
89
99
90
- if (
91
- animationUrl ===
92
- "https://cdn.mikn.dev/vroid/hi.vrma"
93
- ) {
100
+ if ( loop ) {
101
+ action . setLoop ( LoopRepeat , Infinity ) ;
102
+ } else {
94
103
action . setLoop ( LoopOnce , 1 ) ;
95
104
action . clampWhenFinished = true ;
96
- } else {
97
- action . setLoop ( LoopRepeat , Infinity ) ;
98
105
}
99
106
100
107
action . play ( ) ;
101
108
setMixer ( animationMixer ) ;
102
109
} else {
103
- console . error (
104
- "VRM model or humanoid is not loaded correctly." ,
105
- ) ;
110
+ console . error ( "VRM model or humanoid is not loaded correctly." ) ;
106
111
}
107
112
}
108
113
} ,
109
114
undefined ,
110
115
( error : Error ) => {
111
- console . error (
112
- "An error occurred while loading the animation:" ,
113
- error ,
114
- ) ;
116
+ console . error ( "An error occurred while loading the animation:" , error ) ;
115
117
} ,
116
118
) ;
117
119
} ;
@@ -130,14 +132,13 @@ export function VRM() {
130
132
< div className = "flex justify-center items-center w-96 h-96" >
131
133
{ ! isLoaded ? (
132
134
< div className = "flex items-center justify-center p-4" >
133
- < AiOutlineLoading3Quarters
134
- className = "animate-spin text-primary"
135
- size = { 80 }
135
+ < span
136
+ className = "loading loading-xl loading-spinner text-primary"
136
137
/>
137
138
</ div >
138
139
) : (
139
140
< Canvas camera = { { position : [ 0 , 0 , 3 ] } } >
140
- < ambientLight intensity = { 2.1 } />
141
+ < ambientLight intensity = { 1.5 } />
141
142
< VRMModel vrm = { vrm } mixer = { mixer } />
142
143
</ Canvas >
143
144
) }
0 commit comments