From 7dfb3ceaeb1f560d2359a890f5828a2c3ce2c62e Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 30 Jan 2026 14:50:40 +0900 Subject: [PATCH 01/11] init --- .../README.md.ja | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 specification/VRMC_vrm_expressions_joint-1.0/README.md.ja diff --git a/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja b/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja new file mode 100644 index 0000000..dc8d922 --- /dev/null +++ b/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja @@ -0,0 +1,156 @@ +# VRMC_vrm_expressions_joint + +> [!NOTE] +> 名前検討中。 +> vrm_expression_node_transform が正確な気がしてきた。 + +## Contributors + +- 進藤 哲郎 + +## Status + +draft + +## Dependencies + +Written against the glTF 2.0 spec and VRMC_vrm-1.0 extension. + +## Overview + +VRMC_vrm-1.0 の expression に node の移動と回転を加えます。 + +## glTF Schema Updates + +### JSON Schema + +```json +{ + "extensionsUsed": [ + "VRMC_vrm" + "VRMC_vrm_expressions_joint", + ], + "extensions": { + "VRMC_vrm": { + // VRM extension + "specVersion": "1.0", + "humanoid": {}, + "meta": {}, + "firstPerson": {}, + + "expressions": { + "preset": { + "aa": { /* expression object */ }, + "angry": { /* expression object */ }, + "blink": { + "isBinary": false, + /* ここから */ + "jointTransformBinds": [ + { + "node": 1, + "translation": [1, 2, 3], + "rotation": [0, 0, 0, 1], + }, + ], + /* ここまで */ + "overrideBlink": "none", + "overrideLookAt": "none", + "overrideMouth": "none" + }, + "blinkLeft": { /* expression object */ }, + "blinkRight": { /* expression object */ }, + "ee": { /* expression object */ }, + "happy": { /* expression object */ }, + "ih": { /* expression object */ }, + "lookDown": { /* expression object */ }, + "lookLeft": { /* expression object */ }, + "lookRight": { /* expression object */ }, + "lookUp": { /* expression object */ }, + "neutral": { /* expression object */ }, + "oh": { /* expression object */ }, + "ou": { /* expression object */ }, + "relaxed": { /* expression object */ }, + "sad": { /* expression object */ }, + "surprised": { /* expression object */ } + } + "custom": { + "custom_name_1": { /* expression object */ }, + "custom_name_2": { /* expression object */ }, + }, + }, + "lookAt": {}, + }, + + "VRMC_springBone": {}, + "VRMC_node_constraint": {} + }, + // glTF-2.0 + "materials": [ + "extensions": { + "VMRC_materials_mtoon": {} + } + ], +} +``` + +### expression object + +| 名前 | 備考 | +| :-------------------- | :--------------------------------------------------------------------------------- | +| nodeTransformBinds | NodeTransformBind(後述) のリスト | + +### NodeTransformBind + +Expression と Node の移動と回転を結びつけます。 + +> [!NOTE] +> TRS の T と R。Sはやらない方針。 +> エラーにならないがはねるべき不正値が多い。(0以下の値、not uniform) +> 子孫に伝搬していって、子孫で問題が発生する +> springBone, constraint など他の機能と組み合わさったときに問題が発生する +> T は危険性が比較的少ない(NAN以外は正常値) +> R は危険性が比較的少ない(正規化された回転Quaternionは正常値) +> 部品の表示、非表示をしたい場合は、`KHR_node_visibility` など別の方法で対応したい。 + +| 名前 | 備考 | +|:------------|:----------------------------------------------| +| node | 対象のnode のindex | +| translation | 適用したときの移動値(float3) | +| rotaion | 適用したときの回転値(float4) | + +#### Logic + +localTransfrom と localRotation を上書きする。 + +```cs +// Unity試作版 +expression.transform.SetLocalPositionAndRotation( + init.LocalPosition + expression.Translation * weight, + Quaternion.Slerp(init.LocalRotation, init.LocalRotation * expression.Rotation, weight) + ); +``` + +#### 処理順 + +- ControlRig +- Constraint +- LookAt +- Expression // これ +- SpringBone + +> [!NOTE] +> Expression を Constraint の入力にできない。 +> ControlRig を SpringBone の前にした方がいいのでは? + +```cs + // 4. Gaze control + var eyeDirection = LookAt.Process(); + + // 5. Apply Expression + // LookAt の角度制限などはこちらで処理されます。 + Expression.Process(eyeDirection, _initPose); // この中 + + // 6. SpringBone + SpringBone.Process(Time.deltaTime); +``` + From bc5646247348ab518f1b4f95cc35ba9d4bf98d23 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 30 Jan 2026 17:07:41 +0900 Subject: [PATCH 02/11] use scale --- .../README.md.ja | 54 ++++++++----------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja b/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja index dc8d922..983b6c0 100644 --- a/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja +++ b/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja @@ -18,7 +18,7 @@ Written against the glTF 2.0 spec and VRMC_vrm-1.0 extension. ## Overview -VRMC_vrm-1.0 の expression に node の移動と回転を加えます。 +VRMC_vrm-1.0 の expression に node の変形を加えます。 ## glTF Schema Updates @@ -44,18 +44,23 @@ VRMC_vrm-1.0 の expression に node の移動と回転を加えます。 "angry": { /* expression object */ }, "blink": { "isBinary": false, - /* ここから */ - "jointTransformBinds": [ - { - "node": 1, - "translation": [1, 2, 3], - "rotation": [0, 0, 0, 1], - }, - ], - /* ここまで */ "overrideBlink": "none", "overrideLookAt": "none", "overrideMouth": "none" + /* ここから */ + "extensions": { + "VRMC_vrm_expressions_joint" { + "jointTransformBinds": [ + { + "node": 1, + "translation": [1, 2, 3], + "rotation": [0, 0, 0, 1], + "scale": [1, 2, 3], + }, + ], + }, + }, + /* ここまで */ }, "blinkLeft": { /* expression object */ }, "blinkRight": { /* expression object */ }, @@ -93,34 +98,24 @@ VRMC_vrm-1.0 の expression に node の移動と回転を加えます。 } ``` -### expression object - -| 名前 | 備考 | -| :-------------------- | :--------------------------------------------------------------------------------- | -| nodeTransformBinds | NodeTransformBind(後述) のリスト | - ### NodeTransformBind -Expression と Node の移動と回転を結びつけます。 +Expression と Node のローカル TRS を結びつけます。 > [!NOTE] -> TRS の T と R。Sはやらない方針。 -> エラーにならないがはねるべき不正値が多い。(0以下の値、not uniform) -> 子孫に伝搬していって、子孫で問題が発生する -> springBone, constraint など他の機能と組み合わさったときに問題が発生する -> T は危険性が比較的少ない(NAN以外は正常値) -> R は危険性が比較的少ない(正規化された回転Quaternionは正常値) -> 部品の表示、非表示をしたい場合は、`KHR_node_visibility` など別の方法で対応したい。 +> Scale と spring など組み合わせで表示が乱れる設定はありうる。 +> モデル作成者に委ねる。 | 名前 | 備考 | |:------------|:----------------------------------------------| | node | 対象のnode のindex | | translation | 適用したときの移動値(float3) | | rotaion | 適用したときの回転値(float4) | +| scale | 適用したときの回転値(float3)。負の値禁止 | #### Logic -localTransfrom と localRotation を上書きする。 +node local の TRS を上書きする。 ```cs // Unity試作版 @@ -128,20 +123,17 @@ expression.transform.SetLocalPositionAndRotation( init.LocalPosition + expression.Translation * weight, Quaternion.Slerp(init.LocalRotation, init.LocalRotation * expression.Rotation, weight) ); +expression.transform.localScale = expression.Scale * weight; ``` #### 処理順 - ControlRig -- Constraint -- LookAt +- LookAt // yaw, pitch 値の確定 - Expression // これ +- Constraint - SpringBone -> [!NOTE] -> Expression を Constraint の入力にできない。 -> ControlRig を SpringBone の前にした方がいいのでは? - ```cs // 4. Gaze control var eyeDirection = LookAt.Process(); From 311fee676361861efe3dfc2daba731acc188443d Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 30 Jan 2026 17:10:19 +0900 Subject: [PATCH 03/11] humanoid bone --- .../VRMC_vrm_expressions_joint-1.0/README.md.ja | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja b/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja index 983b6c0..80d26b4 100644 --- a/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja +++ b/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja @@ -106,12 +106,12 @@ Expression と Node のローカル TRS を結びつけます。 > Scale と spring など組み合わせで表示が乱れる設定はありうる。 > モデル作成者に委ねる。 -| 名前 | 備考 | -|:------------|:----------------------------------------------| -| node | 対象のnode のindex | -| translation | 適用したときの移動値(float3) | -| rotaion | 適用したときの回転値(float4) | -| scale | 適用したときの回転値(float3)。負の値禁止 | +| 名前 | 備考 | +|:------------|:----------------------------------------------------------------------------| +| node | 対象のnode のindex。humanoid bone と子孫にhumaniod bone を持つ node は禁止。| +| translation | 適用したときの移動値(float3) | +| rotaion | 適用したときの回転値(float4) | +| scale | 適用したときの回転値(float3)。負の値禁止 | #### Logic From 9a05d117b43c757cc68d3a5abcab383568d0c274 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 3 Feb 2026 22:45:22 +0900 Subject: [PATCH 04/11] add schema --- .../README.md.ja | 4 +- ...ssions_joint.nodeTransformBind.schema.json | 51 +++++++++++++++++++ .../VRMC_vrm_expressions_joint.schema.json | 20 ++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.nodeTransformBind.schema.json create mode 100644 specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.schema.json diff --git a/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja b/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja index 80d26b4..00ac376 100644 --- a/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja +++ b/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja @@ -24,6 +24,8 @@ VRMC_vrm-1.0 の expression に node の変形を加えます。 ### JSON Schema +[VRMC_vrm_expressions_joint.schema.json](schema/VRMC_vrm_expressions_joint.schema.json) + ```json { "extensionsUsed": [ @@ -50,7 +52,7 @@ VRMC_vrm-1.0 の expression に node の変形を加えます。 /* ここから */ "extensions": { "VRMC_vrm_expressions_joint" { - "jointTransformBinds": [ + "nodeTransformBinds": [ { "node": 1, "translation": [1, 2, 3], diff --git a/specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.nodeTransformBind.schema.json b/specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.nodeTransformBind.schema.json new file mode 100644 index 0000000..8a78aaa --- /dev/null +++ b/specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.nodeTransformBind.schema.json @@ -0,0 +1,51 @@ +{ + "title": "NodeTransformBind", + "type": "object", + "description": "Node transform associated with a expression", + "allOf": [ { "$ref": "glTFProperty.schema.json" } ], + "properties": { + "node": { + "allOf": [{ "$ref": "glTFid.schema.json" }], + "description": "The node index." + }, + "rotation": { + "type": "array", + "description": "The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar.", + "items": { + "type": "number", + "minimum": -1.0, + "maximum": 1.0 + }, + "minItems": 4, + "maxItems": 4, + "default": [0.0, 0.0, 0.0, 1.0] + }, + "scale": { + "type": "array", + "description": "The node's non-uniform scale, given as the scaling factors along the x, y, and z axes.", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3, + "default": [1.0, 1.0, 1.0] + }, + "translation": { + "type": "array", + "description": "The node's translation along the x, y, and z axes.", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3, + "default": [0.0, 0.0, 0.0] + }, + "extensions": { }, + "extras": { } + }, + "required": [ + "node", + "index", + "weight" + ] +} diff --git a/specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.schema.json b/specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.schema.json new file mode 100644 index 0000000..855b771 --- /dev/null +++ b/specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.schema.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema", + "title": "VRMC_vrm_expression_joint extension", + "type": "object", + "description": "glTF extension that extends expression of VRMC_vrm.", + "allOf": [{ "$ref": "glTFProperty.schema.json" }], + "properties": { + "nodeTransformBinds": { + "type": "array", + "description": "Specify a node transform", + "items": { + "$ref": "VRMC_vrm_expressions_joint.nodeTransformBind.schema.json" + }, + "minItems": 1 + }, + "extensions": {}, + "extras": {} + }, + "required": ["specVersion"] +} From eb32db9140c3dddf0befd5d6a641df443026683f Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 3 Feb 2026 22:48:16 +0900 Subject: [PATCH 05/11] rename to VRMC_vrm_expressions_node_transform from VRMC_vrm_expressions_joint --- .../README.md.ja | 9 ++++----- ...essions_node_transform.nodeTransformBind.schema.json} | 0 .../VRMC_vrm_expressions_node_transform.schema.json} | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) rename specification/{VRMC_vrm_expressions_joint-1.0 => VRMC_vrm_expressions_node_transform-1.0}/README.md.ja (93%) rename specification/{VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.nodeTransformBind.schema.json => VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json} (100%) rename specification/{VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.schema.json => VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.schema.json} (75%) diff --git a/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja similarity index 93% rename from specification/VRMC_vrm_expressions_joint-1.0/README.md.ja rename to specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja index 00ac376..36872ca 100644 --- a/specification/VRMC_vrm_expressions_joint-1.0/README.md.ja +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja @@ -1,8 +1,7 @@ -# VRMC_vrm_expressions_joint +# VRMC_vrm_expressions_node_transform > [!NOTE] > 名前検討中。 -> vrm_expression_node_transform が正確な気がしてきた。 ## Contributors @@ -24,13 +23,13 @@ VRMC_vrm-1.0 の expression に node の変形を加えます。 ### JSON Schema -[VRMC_vrm_expressions_joint.schema.json](schema/VRMC_vrm_expressions_joint.schema.json) +[schema.json](schema/VRMC_vrm_expressions_node_transform.schema.json) ```json { "extensionsUsed": [ "VRMC_vrm" - "VRMC_vrm_expressions_joint", + "VRMC_vrm_expressions_node_transform", ], "extensions": { "VRMC_vrm": { @@ -51,7 +50,7 @@ VRMC_vrm-1.0 の expression に node の変形を加えます。 "overrideMouth": "none" /* ここから */ "extensions": { - "VRMC_vrm_expressions_joint" { + "VRMC_vrm_expressions_node_transform" { "nodeTransformBinds": [ { "node": 1, diff --git a/specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.nodeTransformBind.schema.json b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json similarity index 100% rename from specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.nodeTransformBind.schema.json rename to specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json diff --git a/specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.schema.json b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.schema.json similarity index 75% rename from specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.schema.json rename to specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.schema.json index 855b771..62c033b 100644 --- a/specification/VRMC_vrm_expressions_joint-1.0/schema/VRMC_vrm_expressions_joint.schema.json +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-04/schema", - "title": "VRMC_vrm_expression_joint extension", + "title": "VRMC_vrm_expression_node_transform extension", "type": "object", "description": "glTF extension that extends expression of VRMC_vrm.", "allOf": [{ "$ref": "glTFProperty.schema.json" }], @@ -9,7 +9,7 @@ "type": "array", "description": "Specify a node transform", "items": { - "$ref": "VRMC_vrm_expressions_joint.nodeTransformBind.schema.json" + "$ref": "VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json" }, "minItems": 1 }, From 6be60d9aa715b341474e10548c6d680ed795c6b8 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 3 Feb 2026 22:57:30 +0900 Subject: [PATCH 06/11] note jaw --- .../VRMC_vrm_expressions_node_transform-1.0/README.md.ja | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja index 36872ca..ab385ef 100644 --- a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja @@ -103,13 +103,17 @@ VRMC_vrm-1.0 の expression に node の変形を加えます。 Expression と Node のローカル TRS を結びつけます。 +> [!NOTE] +> humanoid bone と子孫にhumanoid bone を持つ node は禁止。 +> ただし、jaw は除外していいのでははいか。 + > [!NOTE] > Scale と spring など組み合わせで表示が乱れる設定はありうる。 > モデル作成者に委ねる。 | 名前 | 備考 | |:------------|:----------------------------------------------------------------------------| -| node | 対象のnode のindex。humanoid bone と子孫にhumaniod bone を持つ node は禁止。| +| node | 対象のnode のindex。humanoid bone と子孫にhumanoid bone を持つ node は禁止。| | translation | 適用したときの移動値(float3) | | rotaion | 適用したときの回転値(float4) | | scale | 適用したときの回転値(float3)。負の値禁止 | From ef26725de5d4b4f153c2b8b238ee2b87c4955324 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Thu, 5 Feb 2026 15:58:42 +0900 Subject: [PATCH 07/11] offsetT, offsetR, targetS --- .../README.md.ja | 34 +++++++++++-------- ...de_transform.nodeTransformBind.schema.json | 28 +++++++-------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja index ab385ef..ac3923b 100644 --- a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja @@ -54,9 +54,9 @@ VRMC_vrm-1.0 の expression に node の変形を加えます。 "nodeTransformBinds": [ { "node": 1, - "translation": [1, 2, 3], - "rotation": [0, 0, 0, 1], - "scale": [1, 2, 3], + "offsetTranslation": [1, 2, 3], + "offsetRotation": [0, 0, 0, 1], + "targetScale": [1, 2, 3], }, ], }, @@ -101,7 +101,7 @@ VRMC_vrm-1.0 の expression に node の変形を加えます。 ### NodeTransformBind -Expression と Node のローカル TRS を結びつけます。 +Expression と Node のローカルTransform を結びつけます。 > [!NOTE] > humanoid bone と子孫にhumanoid bone を持つ node は禁止。 @@ -111,24 +111,30 @@ Expression と Node のローカル TRS を結びつけます。 > Scale と spring など組み合わせで表示が乱れる設定はありうる。 > モデル作成者に委ねる。 -| 名前 | 備考 | -|:------------|:----------------------------------------------------------------------------| -| node | 対象のnode のindex。humanoid bone と子孫にhumanoid bone を持つ node は禁止。| -| translation | 適用したときの移動値(float3) | -| rotaion | 適用したときの回転値(float4) | -| scale | 適用したときの回転値(float3)。負の値禁止 | +| 名前 | 備考 | +|:------------------|:-------------------------------------------------------------------| +| node | 対象のnode のindex。自身か子孫が humanoid bone である node は禁止。| +| offsetTranslation | 適用したときの移動値(float3) | +| offsetRotaion | 適用したときの回転値(float4) | +| targetScale | 適用したときの拡大値(float3)。負の値禁止。non uniform 可 | #### Logic -node local の TRS を上書きする。 +0-1 で線形に影響が出る、かつ無効値を表現できるように始点と終点を以下のように定義する。 + +|type|始点 |終点 |無効値 | value | +|----|------|----------|---------|-----------------------------------| +| T | init | init + t |(0,0,0) | T = init + t * weight | +| R | init | r * init |(0,0,0,1)| R = slerp(init, r * init, weight) | +| S | init | s |init | S = lerp(init, s, weight) | ```cs // Unity試作版 expression.transform.SetLocalPositionAndRotation( - init.LocalPosition + expression.Translation * weight, - Quaternion.Slerp(init.LocalRotation, init.LocalRotation * expression.Rotation, weight) + init.LocalPosition + expression.OffsetTranslation * weight, + Quaternion.Slerp(init.LocalRotation, init.LocalRotation * expression.OffsetRotation, weight) ); -expression.transform.localScale = expression.Scale * weight; +expression.transform.localScale = Vector3.lerp(init.loccalScale, expression.TargetScale, weight); ``` #### 処理順 diff --git a/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json index 8a78aaa..4109ecd 100644 --- a/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json @@ -8,9 +8,19 @@ "allOf": [{ "$ref": "glTFid.schema.json" }], "description": "The node index." }, - "rotation": { + "offsetTranslation": { "type": "array", - "description": "The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar.", + "description": "t = lerp(init_t, init_t + t, expression_weight)", + "items": { + "type": "number" + }, + "minItems": 3, + "maxItems": 3, + "default": [0.0, 0.0, 0.0] + }, + "offsetRotation": { + "type": "array", + "description": "r = slerp(init_r, r * init_r, expression_weight)", "items": { "type": "number", "minimum": -1.0, @@ -20,9 +30,9 @@ "maxItems": 4, "default": [0.0, 0.0, 0.0, 1.0] }, - "scale": { + "targetScale": { "type": "array", - "description": "The node's non-uniform scale, given as the scaling factors along the x, y, and z axes.", + "description": "s = lerp(init_s, s, expression_weight)", "items": { "type": "number" }, @@ -30,16 +40,6 @@ "maxItems": 3, "default": [1.0, 1.0, 1.0] }, - "translation": { - "type": "array", - "description": "The node's translation along the x, y, and z axes.", - "items": { - "type": "number" - }, - "minItems": 3, - "maxItems": 3, - "default": [0.0, 0.0, 0.0] - }, "extensions": { }, "extras": { } }, From b43ce9979d1302016089a739a011080fb4371c42 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 13 Feb 2026 15:53:24 +0900 Subject: [PATCH 08/11] targetScale to offsetScale --- .../VRMC_vrm_expressions_node_transform-1.0/README.md.ja | 8 ++++---- ...pressions_node_transform.nodeTransformBind.schema.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja index ac3923b..72dd465 100644 --- a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja @@ -56,7 +56,7 @@ VRMC_vrm-1.0 の expression に node の変形を加えます。 "node": 1, "offsetTranslation": [1, 2, 3], "offsetRotation": [0, 0, 0, 1], - "targetScale": [1, 2, 3], + "offsetScale": [1, 2, 3], }, ], }, @@ -116,7 +116,7 @@ Expression と Node のローカルTransform を結びつけます。 | node | 対象のnode のindex。自身か子孫が humanoid bone である node は禁止。| | offsetTranslation | 適用したときの移動値(float3) | | offsetRotaion | 適用したときの回転値(float4) | -| targetScale | 適用したときの拡大値(float3)。負の値禁止。non uniform 可 | +| offsetScale | 適用したときの拡大値(float3)。負の値禁止。non uniform 可 | #### Logic @@ -126,7 +126,7 @@ Expression と Node のローカルTransform を結びつけます。 |----|------|----------|---------|-----------------------------------| | T | init | init + t |(0,0,0) | T = init + t * weight | | R | init | r * init |(0,0,0,1)| R = slerp(init, r * init, weight) | -| S | init | s |init | S = lerp(init, s, weight) | +| S | init | s |(0,0,0) | S = lerp(init, init * s, weight) | ```cs // Unity試作版 @@ -134,7 +134,7 @@ expression.transform.SetLocalPositionAndRotation( init.LocalPosition + expression.OffsetTranslation * weight, Quaternion.Slerp(init.LocalRotation, init.LocalRotation * expression.OffsetRotation, weight) ); -expression.transform.localScale = Vector3.lerp(init.loccalScale, expression.TargetScale, weight); +expression.transform.localScale = Vector3.lerp(init.loccalScale, init.localScale * expression.OffsetScale, weight); ``` #### 処理順 diff --git a/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json index 4109ecd..d13fd6d 100644 --- a/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json @@ -30,7 +30,7 @@ "maxItems": 4, "default": [0.0, 0.0, 0.0, 1.0] }, - "targetScale": { + "offsetScale": { "type": "array", "description": "s = lerp(init_s, s, expression_weight)", "items": { From 83194edb9706fc9aa8d869c90513d9c9c1b0ac81 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 30 Jun 2026 12:48:36 +0900 Subject: [PATCH 09/11] offset to relative --- .../README.md.ja | 39 +++++++++---------- ...de_transform.nodeTransformBind.schema.json | 6 +-- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja index 72dd465..8801f9a 100644 --- a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja @@ -11,7 +11,7 @@ draft -## Dependencies +## Dependencies Written against the glTF 2.0 spec and VRMC_vrm-1.0 extension. @@ -54,14 +54,14 @@ VRMC_vrm-1.0 の expression に node の変形を加えます。 "nodeTransformBinds": [ { "node": 1, - "offsetTranslation": [1, 2, 3], - "offsetRotation": [0, 0, 0, 1], - "offsetScale": [1, 2, 3], + "relativeTranslation": [1, 2, 3], + "relativeRotation": [0, 0, 0, 1], + "relativeScale": [1, 2, 3], }, ], }, }, - /* ここまで */ + /* ここまで */ }, "blinkLeft": { /* expression object */ }, "blinkRight": { /* expression object */ }, @@ -111,30 +111,30 @@ Expression と Node のローカルTransform を結びつけます。 > Scale と spring など組み合わせで表示が乱れる設定はありうる。 > モデル作成者に委ねる。 -| 名前 | 備考 | -|:------------------|:-------------------------------------------------------------------| -| node | 対象のnode のindex。自身か子孫が humanoid bone である node は禁止。| -| offsetTranslation | 適用したときの移動値(float3) | -| offsetRotaion | 適用したときの回転値(float4) | -| offsetScale | 適用したときの拡大値(float3)。負の値禁止。non uniform 可 | +| 名前 | 備考 | +| :---------------- | :------------------------------------------------------------------ | +| node | 対象のnode のindex。自身か子孫が humanoid bone である node は禁止。 | +| relativeTranslation | 適用したときの移動値(float3) | +| relativeRotaion | 適用したときの回転値(float4) | +| relativeScale | 適用したときの拡大値(float3)。負の値禁止。non uniform 可 | #### Logic 0-1 で線形に影響が出る、かつ無効値を表現できるように始点と終点を以下のように定義する。 -|type|始点 |終点 |無効値 | value | -|----|------|----------|---------|-----------------------------------| -| T | init | init + t |(0,0,0) | T = init + t * weight | -| R | init | r * init |(0,0,0,1)| R = slerp(init, r * init, weight) | -| S | init | s |(0,0,0) | S = lerp(init, init * s, weight) | +| type | 始点 | 終点 | 無効値 | value | +| ---- | ---- | --------- | --------- | ---------------------------------- | +| T | init | init + t | (0,0,0) | T = init + t \* weight | +| R | init | r \* init | (0,0,0,1) | R = slerp(init, r \* init, weight) | +| S | init | s | (0,0,0) | S = lerp(init, init \* s, weight) | ```cs // Unity試作版 expression.transform.SetLocalPositionAndRotation( - init.LocalPosition + expression.OffsetTranslation * weight, - Quaternion.Slerp(init.LocalRotation, init.LocalRotation * expression.OffsetRotation, weight) + init.LocalPosition + expression.RelativeTranslation * weight, + Quaternion.Slerp(init.LocalRotation, init.LocalRotation * expression.RelativeRotation, weight) ); -expression.transform.localScale = Vector3.lerp(init.loccalScale, init.localScale * expression.OffsetScale, weight); +expression.transform.localScale = Vector3.lerp(init.loccalScale, init.localScale * expression.RelativeScale, weight); ``` #### 処理順 @@ -156,4 +156,3 @@ expression.transform.localScale = Vector3.lerp(init.loccalScale, init.localScale // 6. SpringBone SpringBone.Process(Time.deltaTime); ``` - diff --git a/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json index d13fd6d..6cb0827 100644 --- a/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json @@ -8,7 +8,7 @@ "allOf": [{ "$ref": "glTFid.schema.json" }], "description": "The node index." }, - "offsetTranslation": { + "relativeTranslation": { "type": "array", "description": "t = lerp(init_t, init_t + t, expression_weight)", "items": { @@ -18,7 +18,7 @@ "maxItems": 3, "default": [0.0, 0.0, 0.0] }, - "offsetRotation": { + "relativeRotation": { "type": "array", "description": "r = slerp(init_r, r * init_r, expression_weight)", "items": { @@ -30,7 +30,7 @@ "maxItems": 4, "default": [0.0, 0.0, 0.0, 1.0] }, - "offsetScale": { + "relativeScale": { "type": "array", "description": "s = lerp(init_s, s, expression_weight)", "items": { From 0468f6e0747875ff4ab3dff5199743253ac927d9 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 30 Jun 2026 13:11:34 +0900 Subject: [PATCH 10/11] targetScale --- .../README.md.ja | 54 ++++++++----------- ...de_transform.nodeTransformBind.schema.json | 8 +-- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja index 8801f9a..44a49b9 100644 --- a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja @@ -56,7 +56,7 @@ VRMC_vrm-1.0 の expression に node の変形を加えます。 "node": 1, "relativeTranslation": [1, 2, 3], "relativeRotation": [0, 0, 0, 1], - "relativeScale": [1, 2, 3], + "targetScale": [1, 2, 3], }, ], }, @@ -111,33 +111,16 @@ Expression と Node のローカルTransform を結びつけます。 > Scale と spring など組み合わせで表示が乱れる設定はありうる。 > モデル作成者に委ねる。 -| 名前 | 備考 | -| :---------------- | :------------------------------------------------------------------ | -| node | 対象のnode のindex。自身か子孫が humanoid bone である node は禁止。 | +| 名前 | 備考 | +| :------------------ | :------------------------------------------------------------------ | +| node | 対象のnode のindex。自身か子孫が humanoid bone である node は禁止。 | | relativeTranslation | 適用したときの移動値(float3) | | relativeRotaion | 適用したときの回転値(float4) | -| relativeScale | 適用したときの拡大値(float3)。負の値禁止。non uniform 可 | +| targetScale | 適用したときの拡大値(float3)。負の値禁止。non uniform 可 | -#### Logic +## 詳細 -0-1 で線形に影響が出る、かつ無効値を表現できるように始点と終点を以下のように定義する。 - -| type | 始点 | 終点 | 無効値 | value | -| ---- | ---- | --------- | --------- | ---------------------------------- | -| T | init | init + t | (0,0,0) | T = init + t \* weight | -| R | init | r \* init | (0,0,0,1) | R = slerp(init, r \* init, weight) | -| S | init | s | (0,0,0) | S = lerp(init, init \* s, weight) | - -```cs -// Unity試作版 -expression.transform.SetLocalPositionAndRotation( - init.LocalPosition + expression.RelativeTranslation * weight, - Quaternion.Slerp(init.LocalRotation, init.LocalRotation * expression.RelativeRotation, weight) - ); -expression.transform.localScale = Vector3.lerp(init.loccalScale, init.localScale * expression.RelativeScale, weight); -``` - -#### 処理順 +### 処理順 - ControlRig - LookAt // yaw, pitch 値の確定 @@ -145,14 +128,21 @@ expression.transform.localScale = Vector3.lerp(init.loccalScale, init.localScale - Constraint - SpringBone -```cs - // 4. Gaze control - var eyeDirection = LookAt.Process(); +### translation & rotation - // 5. Apply Expression - // LookAt の角度制限などはこちらで処理されます。 - Expression.Process(eyeDirection, _initPose); // この中 +``` +expression.transform.SetLocalPositionAndRotation( + // T: init + lerp(zeroVector3, relative, weight) + init.LocalPosition + Vector3.Lerp(Vector3.zero, expression.RelativeTranslation, weight), + // R: init * slerp(identityQuaternion, relative, weight) + init.LocalRotation * Quaternion.Slerp(Quaternion.identity, expression.RelativeRotation, weight) + ); +``` - // 6. SpringBone - SpringBone.Process(Time.deltaTime); +### scale + +- 初期姿勢とtargetScaleの間を線形に補完する + +``` +expression.transform.localScale = Vector3.lerp(init.loccalScale, init.localScale * expression.targetScale, weight); ``` diff --git a/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json index 6cb0827..d8f158c 100644 --- a/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/schema/VRMC_vrm_expressions_node_transform.nodeTransformBind.schema.json @@ -10,7 +10,7 @@ }, "relativeTranslation": { "type": "array", - "description": "t = lerp(init_t, init_t + t, expression_weight)", + "description": "t = init_t + lerp(zero, relativeTranslation, expression_weight)", "items": { "type": "number" }, @@ -20,7 +20,7 @@ }, "relativeRotation": { "type": "array", - "description": "r = slerp(init_r, r * init_r, expression_weight)", + "description": "r = init_r * slerp(identity, relativeRotation, expression_weight)", "items": { "type": "number", "minimum": -1.0, @@ -30,9 +30,9 @@ "maxItems": 4, "default": [0.0, 0.0, 0.0, 1.0] }, - "relativeScale": { + "targetScale": { "type": "array", - "description": "s = lerp(init_s, s, expression_weight)", + "description": "s = lerp(init_s, targetScale, expression_weight)", "items": { "type": "number" }, From cf6a721e79aeb2657dead9f22f0f0448ca8d7356 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 30 Jun 2026 13:22:23 +0900 Subject: [PATCH 11/11] =?UTF-8?q?=E8=A4=87=E6=95=B0=E5=80=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../README.md.ja | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja index 44a49b9..7c0baa3 100644 --- a/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja +++ b/specification/VRMC_vrm_expressions_node_transform-1.0/README.md.ja @@ -146,3 +146,26 @@ expression.transform.SetLocalPositionAndRotation( ``` expression.transform.localScale = Vector3.lerp(init.loccalScale, init.localScale * expression.targetScale, weight); ``` + +### 同じボーンに対して複数の NodeTransform の重みが有効なったとき + +``` +expression.transform.SetLocalPositionAndRotation( + // T: init + lerp(zeroVector3, relative, weight) + init.LocalPosition + + Vector3.Lerp(Vector3.zero, expression.RelativeTranslation0, weight0) + + Vector3.Lerp(Vector3.zero, expression.RelativeTranslation1, weight1) + + Vector3.Lerp(Vector3.zero, expression.RelativeTranslation2, weight2) + , + // R: init * slerp(identityQuaternion, relative, weight) + init.LocalRotation + * Quaternion.Slerp(Quaternion.identity, expression.RelativeRotation0, weight0) + * Quaternion.Slerp(Quaternion.identity, expression.RelativeRotation1, weight1) + * Quaternion.Slerp(Quaternion.identity, expression.RelativeRotation2, weight2) + ); +``` + +- Transform は一意に決まり自明 +- Rotation の乗算順は expression の定義順 +- Scale に関しては未定義 +