@@ -123,8 +123,11 @@ public void SetVRIK(VRIK setIK)
123123 if ( eventId != null ) IKManager . Instance . RemoveOnPostUpdate ( eventId . Value ) ;
124124 ik = setIK ;
125125
126- LeftArmFixItem = new ArmFixItem ( ik . references . leftShoulder , ik . references . leftUpperArm , ik . references . leftForearm , ik . references . leftHand ) ;
127- RightArmFixItem = new ArmFixItem ( ik . references . rightShoulder , ik . references . rightUpperArm , ik . references . rightForearm , ik . references . rightHand ) ;
126+ // 基準となるTransformを取得(胸が優先、なければルート)
127+ Transform referenceTransform = ik . references . chest ?? ik . references . root ;
128+
129+ LeftArmFixItem = new ArmFixItem ( ik . references . leftShoulder , ik . references . leftUpperArm , ik . references . leftForearm , ik . references . leftHand , referenceTransform ) ;
130+ RightArmFixItem = new ArmFixItem ( ik . references . rightShoulder , ik . references . rightUpperArm , ik . references . rightForearm , ik . references . rightHand , referenceTransform ) ;
128131
129132 // 設定を再読み込み
130133 LoadSettingsValues ( ) ;
@@ -148,8 +151,8 @@ private void ApplyArmTwistFix(ArmFixItem item)
148151 Quaternion currentForearmRotation = item . Forearm . rotation ;
149152
150153 // 1. UpperArmとForearmの現在の回転からTwist成分のみを除去し、Swing成分のみを残す
151- Quaternion upperArmSwingOnly = RemoveTwistFromRotation ( currentUpperArmRotation , item . InitialUpperArmRotation , item . UpperArmTwistAxis ) ;
152- Quaternion forearmSwingOnly = RemoveTwistFromRotation ( currentForearmRotation , item . InitialForearmRotation , item . ForearmTwistAxis ) ;
154+ Quaternion upperArmSwingOnly = RemoveTwistFromRotation ( currentUpperArmRotation , item . InitialUpperArmRotation , item . UpperArmTwistAxis , item ) ;
155+ Quaternion forearmSwingOnly = RemoveTwistFromRotation ( currentForearmRotation , item . InitialForearmRotation , item . ForearmTwistAxis , item ) ;
153156
154157 // 2. Swing成分のみの回転を適用(IKの結果を保持)
155158 item . UpperArm . rotation = upperArmSwingOnly ;
@@ -214,17 +217,45 @@ private void ApplyArmTwistFix(ArmFixItem item)
214217 }
215218
216219 // 回転からTwist成分を除去し、Swing成分のみを残す
217- private Quaternion RemoveTwistFromRotation ( Quaternion currentRotation , Quaternion initialRotation , Vector3 twistAxis )
220+ private Quaternion RemoveTwistFromRotation ( Quaternion currentRotation , Quaternion initialRotation , Vector3 twistAxis , ArmFixItem item )
218221 {
219- // 初期回転からの相対回転を取得
220- Quaternion relativeRotation = currentRotation * Quaternion . Inverse ( initialRotation ) ;
222+ Quaternion relativeRotation ;
221223
222- // Swing-Twist分解でSwing成分のみを抽出
223- Quaternion swing , twist ;
224- SwingTwistDecomposition ( relativeRotation , twistAxis , out swing , out twist ) ;
224+ // 基準Transform(胸またはルート)を取得
225+ Transform referenceTransform = ik . references . chest ?? ik . references . root ;
225226
226- // Swing成分のみを初期回転に適用
227- return swing * initialRotation ;
227+ if ( referenceTransform != null )
228+ {
229+ // 基準Transformを使った相対回転計算
230+ Quaternion currentReferenceRotation = referenceTransform . rotation ;
231+
232+ // 現在の腕の回転を基準Transformからの相対回転として計算
233+ Quaternion currentArmRelativeToReference = Quaternion . Inverse ( currentReferenceRotation ) * currentRotation ;
234+
235+ // 初期状態との相対回転を計算(基準Transformの回転変化の影響を除去)
236+ Quaternion initialArmRelativeToReference = ( initialRotation == item . InitialUpperArmRotation )
237+ ? item . InitialUpperArmRelativeToReference
238+ : item . InitialForearmRelativeToReference ;
239+
240+ relativeRotation = currentArmRelativeToReference * Quaternion . Inverse ( initialArmRelativeToReference ) ;
241+
242+ // Swing-Twist分解でSwing成分のみを抽出
243+ Quaternion swing , twist ;
244+ SwingTwistDecomposition ( relativeRotation , twistAxis , out swing , out twist ) ;
245+
246+ // 結果を基準Transformを基準としたワールド座標に戻す
247+ return currentReferenceRotation * ( swing * initialArmRelativeToReference ) ;
248+ }
249+ else
250+ {
251+ // 基準Transformがない場合は従来の方法
252+ relativeRotation = currentRotation * Quaternion . Inverse ( initialRotation ) ;
253+
254+ Quaternion swing , twist ;
255+ SwingTwistDecomposition ( relativeRotation , twistAxis , out swing , out twist ) ;
256+
257+ return swing * initialRotation ;
258+ }
228259 }
229260
230261 // HandのTwist角度を計算(Swing-Twist分解を使用)
@@ -316,8 +347,15 @@ public class ArmFixItem
316347 // T-ポーズ時の初期回転を保存
317348 public Quaternion InitialUpperArmRotation ;
318349 public Quaternion InitialForearmRotation ;
350+
351+ // 基準Transform(胸またはルート)の初期回転を保存
352+ public Quaternion InitialReferenceRotation ;
353+
354+ // 腕の初期回転を基準Transformからの相対回転として保存
355+ public Quaternion InitialUpperArmRelativeToReference ;
356+ public Quaternion InitialForearmRelativeToReference ;
319357
320- public ArmFixItem ( Transform shoulder , Transform upperArm , Transform forearm , Transform hand )
358+ public ArmFixItem ( Transform shoulder , Transform upperArm , Transform forearm , Transform hand , Transform referenceTransform )
321359 {
322360 Shoulder = shoulder ;
323361 UpperArm = upperArm ;
@@ -336,9 +374,26 @@ public ArmFixItem(Transform shoulder, Transform upperArm, Transform forearm, Tra
336374 // 初期状態のHandの回転を保存
337375 NeutralHandRotation = Quaternion . Inverse ( forearm . rotation ) * hand . rotation ;
338376
339- // T-ポーズ時の初期回転を保存
377+ // T-ポーズ時の絶対回転を保存
340378 InitialUpperArmRotation = upperArm . rotation ;
341379 InitialForearmRotation = forearm . rotation ;
380+
381+ // 基準Transform(胸またはルート)の初期回転を保存
382+ if ( referenceTransform != null )
383+ {
384+ InitialReferenceRotation = referenceTransform . rotation ;
385+
386+ // 腕の回転を基準Transformからの相対回転として保存
387+ InitialUpperArmRelativeToReference = Quaternion . Inverse ( referenceTransform . rotation ) * upperArm . rotation ;
388+ InitialForearmRelativeToReference = Quaternion . Inverse ( referenceTransform . rotation ) * forearm . rotation ;
389+ }
390+ else
391+ {
392+ // 基準Transformがない場合は従来の方法を使用
393+ InitialReferenceRotation = Quaternion . identity ;
394+ InitialUpperArmRelativeToReference = upperArm . rotation ;
395+ InitialForearmRelativeToReference = forearm . rotation ;
396+ }
342397 }
343398 }
344399 }
0 commit comments