@@ -13,12 +13,13 @@ const m1 = new THREE.Matrix4()
1313
1414const FORWARD = new THREE . Vector3 ( 0 , 0 , - 1 )
1515
16- const DIST_CHECK_RATE = 2 // once every second
1716const DIST_MIN_RATE = 1 / 5 // 5 times per second
1817const DIST_MAX_RATE = 1 / 60 // 40 times per second
1918const DIST_MIN = 5 // <= 5m = max rate
2019const DIST_MAX = 60 // >= 60m = min rate
2120
21+ const MAX_GAZE_DISTANCE = 40
22+
2223const material = new THREE . MeshBasicMaterial ( )
2324
2425const AimAxis = {
@@ -285,35 +286,31 @@ export function createVRMFactory(glb, setupMaterial) {
285286
286287 let elapsed = 0
287288 let rate = 0
288- let rateCheckedAt = 999
289289 let rateCheck = true
290+ let distance
291+
292+ const updateRate = ( ) => {
293+ const vrmPos = v1 . setFromMatrixPosition ( vrm . scene . matrix )
294+ const camPos = v2 . setFromMatrixPosition ( hooks . camera . matrixWorld ) // prettier-ignore
295+ distance = vrmPos . distanceTo ( camPos )
296+ const clampedDistance = Math . max ( distance - DIST_MIN , 0 )
297+ const normalizedDistance = Math . min ( clampedDistance / ( DIST_MAX - DIST_MIN ) , 1 ) // prettier-ignore
298+ rate = DIST_MAX_RATE + normalizedDistance * ( DIST_MIN_RATE - DIST_MAX_RATE ) // prettier-ignore
299+ // console.log('distance', distance)
300+ // console.log('rate per second', 1 / rate)
301+ }
302+
290303 const update = delta => {
291304 elapsed += delta
292- let should = true
293- if ( rateCheck ) {
294- // periodically calculate update rate based on distance to camera
295- rateCheckedAt += delta
296- if ( rateCheckedAt >= DIST_CHECK_RATE ) {
297- const vrmPos = v1 . setFromMatrixPosition ( vrm . scene . matrix )
298- const camPos = v2 . setFromMatrixPosition ( hooks . camera . matrixWorld ) // prettier-ignore
299- const distance = vrmPos . distanceTo ( camPos )
300- const clampedDistance = Math . max ( distance - DIST_MIN , 0 )
301- const normalizedDistance = Math . min ( clampedDistance / ( DIST_MAX - DIST_MIN ) , 1 ) // prettier-ignore
302- rate = DIST_MAX_RATE + normalizedDistance * ( DIST_MIN_RATE - DIST_MAX_RATE ) // prettier-ignore
303- // console.log('distance', distance)
304- // console.log('rate per second', 1 / rate)
305- rateCheckedAt = 0
306- }
307- should = elapsed >= rate
308- }
305+ const should = rateCheck ? elapsed >= rate : true
309306 if ( should ) {
310307 mixer . update ( elapsed )
311308 skeleton . bones . forEach ( bone => bone . updateMatrixWorld ( ) )
312309 skeleton . update = THREE . Skeleton . prototype . update
313310 if ( ! currentEmote ) {
314311 updateLocomotion ( delta )
315312 }
316- if ( loco . gazeDir && ( currentEmote ? currentEmote . gaze : true ) ) {
313+ if ( loco . gazeDir && distance < MAX_GAZE_DISTANCE && ( currentEmote ? currentEmote . gaze : true ) ) {
317314 aimBone ( 'neck' , loco . gazeDir , delta , {
318315 minAngle : - 30 ,
319316 maxAngle : 30 ,
@@ -619,6 +616,7 @@ export function createVRMFactory(glb, setupMaterial) {
619616 setEmote,
620617 setFirstPerson,
621618 update,
619+ updateRate,
622620 getBoneTransform,
623621 setLocomotion,
624622 setVisible ( visible ) {
0 commit comments