|
3 | 3 | * Copyright 2010-2026 Three.js Authors |
4 | 4 | * SPDX-License-Identifier: MIT |
5 | 5 | */ |
6 | | -const REVISION = '184'; |
| 6 | +const REVISION = '185dev'; |
7 | 7 |
|
8 | 8 | /** |
9 | 9 | * Represents mouse buttons and interaction types in context of controls. |
@@ -43031,144 +43031,6 @@ class AnimationClip { |
43031 | 43031 |
|
43032 | 43032 | } |
43033 | 43033 |
|
43034 | | - /** |
43035 | | - * Parses the `animation.hierarchy` format and returns a new animation clip. |
43036 | | - * |
43037 | | - * @static |
43038 | | - * @deprecated since r175. |
43039 | | - * @param {Object} animation - A serialized animation clip as JSON. |
43040 | | - * @param {Array<Bone>} bones - An array of bones. |
43041 | | - * @return {?AnimationClip} The new animation clip. |
43042 | | - */ |
43043 | | - static parseAnimation( animation, bones ) { |
43044 | | - |
43045 | | - warn( 'AnimationClip: parseAnimation() is deprecated and will be removed with r185' ); |
43046 | | - |
43047 | | - if ( ! animation ) { |
43048 | | - |
43049 | | - error( 'AnimationClip: No animation in JSONLoader data.' ); |
43050 | | - return null; |
43051 | | - |
43052 | | - } |
43053 | | - |
43054 | | - const addNonemptyTrack = function ( trackType, trackName, animationKeys, propertyName, destTracks ) { |
43055 | | - |
43056 | | - // only return track if there are actually keys. |
43057 | | - if ( animationKeys.length !== 0 ) { |
43058 | | - |
43059 | | - const times = []; |
43060 | | - const values = []; |
43061 | | - |
43062 | | - flattenJSON( animationKeys, times, values, propertyName ); |
43063 | | - |
43064 | | - // empty keys are filtered out, so check again |
43065 | | - if ( times.length !== 0 ) { |
43066 | | - |
43067 | | - destTracks.push( new trackType( trackName, times, values ) ); |
43068 | | - |
43069 | | - } |
43070 | | - |
43071 | | - } |
43072 | | - |
43073 | | - }; |
43074 | | - |
43075 | | - const tracks = []; |
43076 | | - |
43077 | | - const clipName = animation.name || 'default'; |
43078 | | - const fps = animation.fps || 30; |
43079 | | - const blendMode = animation.blendMode; |
43080 | | - |
43081 | | - // automatic length determination in AnimationClip. |
43082 | | - let duration = animation.length || -1; |
43083 | | - |
43084 | | - const hierarchyTracks = animation.hierarchy || []; |
43085 | | - |
43086 | | - for ( let h = 0; h < hierarchyTracks.length; h ++ ) { |
43087 | | - |
43088 | | - const animationKeys = hierarchyTracks[ h ].keys; |
43089 | | - |
43090 | | - // skip empty tracks |
43091 | | - if ( ! animationKeys || animationKeys.length === 0 ) continue; |
43092 | | - |
43093 | | - // process morph targets |
43094 | | - if ( animationKeys[ 0 ].morphTargets ) { |
43095 | | - |
43096 | | - // figure out all morph targets used in this track |
43097 | | - const morphTargetNames = {}; |
43098 | | - |
43099 | | - let k; |
43100 | | - |
43101 | | - for ( k = 0; k < animationKeys.length; k ++ ) { |
43102 | | - |
43103 | | - if ( animationKeys[ k ].morphTargets ) { |
43104 | | - |
43105 | | - for ( let m = 0; m < animationKeys[ k ].morphTargets.length; m ++ ) { |
43106 | | - |
43107 | | - morphTargetNames[ animationKeys[ k ].morphTargets[ m ] ] = -1; |
43108 | | - |
43109 | | - } |
43110 | | - |
43111 | | - } |
43112 | | - |
43113 | | - } |
43114 | | - |
43115 | | - // create a track for each morph target with all zero |
43116 | | - // morphTargetInfluences except for the keys in which |
43117 | | - // the morphTarget is named. |
43118 | | - for ( const morphTargetName in morphTargetNames ) { |
43119 | | - |
43120 | | - const times = []; |
43121 | | - const values = []; |
43122 | | - |
43123 | | - for ( let m = 0; m !== animationKeys[ k ].morphTargets.length; ++ m ) { |
43124 | | - |
43125 | | - const animationKey = animationKeys[ k ]; |
43126 | | - |
43127 | | - times.push( animationKey.time ); |
43128 | | - values.push( ( animationKey.morphTarget === morphTargetName ) ? 1 : 0 ); |
43129 | | - |
43130 | | - } |
43131 | | - |
43132 | | - tracks.push( new NumberKeyframeTrack( '.morphTargetInfluence[' + morphTargetName + ']', times, values ) ); |
43133 | | - |
43134 | | - } |
43135 | | - |
43136 | | - duration = morphTargetNames.length * fps; |
43137 | | - |
43138 | | - } else { |
43139 | | - |
43140 | | - // ...assume skeletal animation |
43141 | | - |
43142 | | - const boneName = '.bones[' + bones[ h ].name + ']'; |
43143 | | - |
43144 | | - addNonemptyTrack( |
43145 | | - VectorKeyframeTrack, boneName + '.position', |
43146 | | - animationKeys, 'pos', tracks ); |
43147 | | - |
43148 | | - addNonemptyTrack( |
43149 | | - QuaternionKeyframeTrack, boneName + '.quaternion', |
43150 | | - animationKeys, 'rot', tracks ); |
43151 | | - |
43152 | | - addNonemptyTrack( |
43153 | | - VectorKeyframeTrack, boneName + '.scale', |
43154 | | - animationKeys, 'scl', tracks ); |
43155 | | - |
43156 | | - } |
43157 | | - |
43158 | | - } |
43159 | | - |
43160 | | - if ( tracks.length === 0 ) { |
43161 | | - |
43162 | | - return null; |
43163 | | - |
43164 | | - } |
43165 | | - |
43166 | | - const clip = new this( clipName, duration, tracks, blendMode ); |
43167 | | - |
43168 | | - return clip; |
43169 | | - |
43170 | | - } |
43171 | | - |
43172 | 43034 | /** |
43173 | 43035 | * Sets the duration of this clip to the duration of its longest keyframe track. |
43174 | 43036 | * |
@@ -43633,6 +43495,11 @@ class LoadingManager { |
43633 | 43495 | */ |
43634 | 43496 | this.resolveURL = function ( url ) { |
43635 | 43497 |
|
| 43498 | + // Normalize to NFC so that Unicode URIs (e.g. from glTF) |
| 43499 | + // are percent-encoded correctly per RFC 3987. |
| 43500 | + |
| 43501 | + url = url.normalize( 'NFC' ); |
| 43502 | + |
43636 | 43503 | if ( urlModifier ) { |
43637 | 43504 |
|
43638 | 43505 | return urlModifier( url ); |
|
0 commit comments