Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.0] Follow new constraint spec #934

Merged
merged 8 commits into from
Mar 17, 2022
Merged

[1.0] Follow new constraint spec #934

merged 8 commits into from
Mar 17, 2022

Conversation

0b5vr
Copy link
Contributor

@0b5vr 0b5vr commented Mar 4, 2022

Description

This PR follows the new constraint spec.

  • type definitions
  • implementations
  • test cases
  • examples

See: vrm-c/vrm-specification#355

Points need review

  • Do the implementations look good?
    • I simply followed the reference implementation example in the spec (+ several obvious optimizations)
  • Do the test cases look good?
    • I don't think it needs to be exhaustive but should be """enough"""
  • Any performance suggestions?

@0b5vr 0b5vr added enhancement New feature or request VRM 1.0 labels Mar 4, 2022
@0b5vr 0b5vr added this to the VRM 1.0 milestone Mar 4, 2022
@0b5vr 0b5vr requested a review from nyamadan March 4, 2022 10:14
@0b5vr 0b5vr self-assigned this Mar 4, 2022
Copy link
Contributor

@nyamadan nyamadan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

自分の理解のために少しコメントを残しました。

またConstraintはroll/rotation/aimの選択式であるため型定義の提案をさせていただきました。

constraintManager.addConstraint(constraint);
} );

const constraint = new THREE_VRM_NODE_CONSTRAINT.VRMAimConstraint( aim, lowerArm );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEMO]

aimがlowerArmに従う。
仕様より +Y 軸がlowerArmのほうにむく。

const constraintBC = new THREE_VRM_NODE_CONSTRAINT.VRMPositionConstraint( cubeC, modelRoot );
constraintBC.setSource( cubeA );
constraintManager.addConstraint( constraintBC );
const constraint = new THREE_VRM_NODE_CONSTRAINT.VRMRollConstraint( roll, hand );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEMO]

rollがhandに従う。手首が回ると肘が回る。伝える軸はY軸

@@ -320,9 +320,9 @@
"VRMC_node_constraint": {
"specVersion": "1.0-draft",
"constraint": {
"rotation": {
"roll": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MEMO

RollConstraintの指定
0番目のノードよりY軸回転の影響を受ける。

@@ -120,9 +125,16 @@

requestAnimationFrame( animate );

const deltaTime = clock.getDelta();
source.rotation.set(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEMO]

ここでquaternionが上書きされる。

target.copy(QUAT_IDENTITY);
public setInitState(): void {
this._dstRestQuat.copy(this.destination.quaternion);
quatInvertCompat(this._invSrcRestQuat.copy(this.source.quaternion));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEMO]

初期化時のquaternionをここで保持しておく。

* What the quatFromTo is intended to be:
*
* ```ts
* const quatFromTo = _quatB.setFromUnitVectors( n0, n1 ).inverse();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEMO]

n0(this._v3RollAxis)→n1の逆元と等価。

@@ -1,10 +1,14 @@
import { AimConstraint } from './AimConstraint';
import { RollConstraint } from './RollConstraint';
import type { RotationConstraint } from './RotationConstraint';

/**
* An object contains one of constraints.
*/
export interface Constraint {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[IMO]
三者択一でしたらこんな感じに型定義してみるのはどうでしょうか。

interface ConstraintBase {
  extensions?: { [name: string]: any };
  extras?: any;
}

interface ContraintWithRoll extends ConstraintBase {
  roll: RollConstraint;
  aim: undefined;
  rotation: undefined;
}

interface ContraintWithAim extends ConstraintBase {
  aim: AimConstraint;
  roll: undefined;
  rotation: undefined;
}

interface ContraintWithRotation extends ConstraintBase {
  rotation: RotationConstraint;
  roll: undefined;
  aim: undefined;
}

/**
 * An object contains one of constraints.
 */
export type Constraint = ContraintWithRoll | ContraintWithAim | ContraintWithRotation;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

説明忘れてましたが、ここの型定義はspecのschemaに準拠するものです。

https://github.com/vrm-c/vrm-specification/blob/c518a9d9a17dfeb32c6056af4c6c5bee2e215672/specification/VRMC_node_constraint-1.0_draft/schema/VRMC_node_constraint.constraint.schema.json

extension および extras はどちらかというと gltfProperty.schema.json に準拠するものです。

https://github.com/KhronosGroup/glTF/blob/main/specification/2.0/schema/glTFProperty.schema.json

gltf-transformの型定義では以下の箇所かな。

https://github.com/donmccurdy/glTF-Transform/blob/3da81241fed236cb39c2698beb595c6631810efc/packages/core/src/types/gltf.ts#L30-L39

提案のコードはちょっとやりすぎじゃないかなあという気がしています。
TypeScriptで簡単にJSON SchemaのOneOfが書ければ良いのですけどね。
ContraintWithRoll 等の型推論ができたとして、実際のコードベース内でどういう恩恵が受けられるか気になります。

Copy link
Contributor

@nyamadan nyamadan Mar 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

型推論の恩恵が得られるケースとしては具体的にはこちらの箇所で型推論が期待できます。

たとえば .roll != null でしたら、 .aim.rotationundefined になると推論できますので、不用意に.aim.rotation にアクセスできません。

image

また、 .aim.rotation.roll すべてが undefined であった場合、どの型にもマッチしなくなるので never 型に推論できます。

image

こちらのsafeUnreachableのようにnever型とマッチする関数を作っておけば例えばConstraintが増えた場合にコンパイルエラーとできます。

確かに型は少し複雑になりますので取り入れるかどうかの判断はお任せします。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ちょっと他にも同様のoneOfあるので、いったんあとで判断でも良いですか。

他のoneOfはこのへんかな: https://github.com/pixiv/three-vrm/blob/1.0/packages/types-vrmc-springbone-1.0/src/SpringBoneColliderShape.ts

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

はい、いったんはこのままで。別のPullRequestなどで対応できればと思います。

/**
* The weight of the constraint.
*/
weight?: number;

extensions?: { [key: string]: { [key: string]: any } };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Q]
ここが二次元の連想配列になっているのは何故でしょうか?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あ。なんかこれはミスってそうだな。ちゃんと調査して直します。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gltf-transform の定義では Record<string, unknown>
たぶん { [name: string]: any } のほうが正解そうですね。直します。

ちなみに実際に拡張名自体以外の情報量が無の拡張として KHR_materials_unlit があるが、こちらは値として {} を使っている模様。うーん、まあいいか。

Copy link
Contributor Author

@0b5vr 0b5vr Mar 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修正しました @ 5cc0ba5
見直したら、他の拡張についても同様のシグネチャが紛れ込んでいるっぽいので、そちらも別PRで直します。

* - objB
* - objC <- this is gonna be given to the function
* - objD <- this is a dummy
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コメント助かります。


describe('when the source is rotated around Z axis', () => {
beforeEach(() => {
source.quaternion.multiply(quatPZ90);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

X軸周りに90度回転してるから、Z軸と重なる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request VRM 1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants