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

Convert to ThreeJS.Vector2 internally in public api. #4473

Merged
merged 6 commits into from
Sep 22, 2023
Merged

Convert to ThreeJS.Vector2 internally in public api. #4473

merged 6 commits into from
Sep 22, 2023

Conversation

diegoteran
Copy link
Collaborator

Fixes #4403

@@ -18,7 +18,7 @@ import {Texture as ThreeTexture, Vector2} from 'three';
import {Filter, MagFilter, MinFilter, Wrap, WrapMode} from '../../three-components/gltf-instance/gltf-2.0.js';
import {Sampler as DefaultedSampler} from '../../three-components/gltf-instance/gltf-defaulted.js';

import {Sampler as SamplerInterface} from './api.js';
import {Sampler as SamplerInterface, Vector2 as Vector2Interface} from './api.js';
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe we should just rename Vector2 to avoid this confusion with three.js? Also, we have a Vector2D and Vector3D in model-viewer-base.js - can we be consistent with those (accept them as valid input)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I initially tried to use Vector2D from model-viewer-base in the api.js file and it wouldn't work. I can give it another go at trying out deleting the api.js Vector2 interface.

rename Vector2 to avoid this confusion with three.js?
You mean rename the Vector2 in api.js?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the interface is necessary so that users don't have to include a toString(). And yes, I mean renaming in api.js. Also check the members for compatibility with Vector2D.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah Vector2D from base.js requires additional imports. Just uploaded a new commit

if (scale == null) {
// Reset scale.
scale = new Vector2(1, 1);
}
this[$setProperty]('repeat', scale);
this[$setProperty]('repeat', new Vector2(scale.x, scale.y));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we have an example that tests this? Did it work before?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes we have a transform Textures example. It did work before on android and Mac, still works. I need to test with iOS.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Wow, I guess three.js must automatically turn a scalar into a vector?

@@ -32,7 +32,7 @@ export declare interface ThreeDOMElementMap {
}

/** A 2D Cartesian coordinate */
export interface Vector2 {
export interface Vector2D {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Okay, so now instead of shadowing three's construct, you're shadowing our existing public class from model-viewer-base. Any reason not to use Vector2DInterface like you did before?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not really, I think this is trying to be an interface for threejs's vector2, so maybe Vector2Interface is better?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sure, SG

@@ -32,7 +32,7 @@ export declare interface ThreeDOMElementMap {
}

/** A 2D Cartesian coordinate */
export interface Vector2 {
export interface Vector2D {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, I think you may have missed this one:

Also check the members for compatibility with Vector2D.

I believe they're u and v, not x and y?

Copy link
Collaborator Author

@diegoteran diegoteran Sep 21, 2023

Choose a reason for hiding this comment

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

Do we want that? I though tthe purpose of this Vector Interface was to not expose threejs' vector2, and ThreeJs Vector2 uses x and y. It seems to me that this interface and Vector2D in base have different purposes. wdyt?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Exactly, we have zero interest in an API consistent with three.js (we're hiding their API). We want an API that is self-consistent and consistent with glTF. We already have an API called Vector2D that uses u and v, so using x and y here would be confusing. Besides, this feature is about textures, which are mapped in a u-v space.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

got it, sgtm

return this[$threeTexture].repeat;
}

get offset(): Vector2|null {
get offset(): Vector2D|null {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I just realized this also needs to change - you're returning a pointer to an internal three.js construct, which means they could then use it to change out internals (in JS every object is pass by reference). You need to use our toVector2D() to make a proper copy.

.to.be.eql(new Vector2(0.2, 0.3), 'offset');
expect(exported_sampler.scale)
.to.be.eql(new Vector2(0.4, 0.5), 'scale');
expect(exported_sampler.offset).to.be.eql({u: 0.2, v: 0.3}, 'offset');
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the trouble is you're actually returning a Vector2D which has a toString method. I would just separate these lines to check the u and v separately.

}

get offset(): Vector2|null {
return this[$threeTexture].offset;
get offset(): Vector2DInterface|null {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: unlike set, here you actually get a real Vector2D.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

do we want the set and get to have different parameter/return value type?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Technically that's the most accurate - we give a specific object back, but accept a broader interface class as input.

Copy link
Collaborator

@elalish elalish left a comment

Choose a reason for hiding this comment

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

Thanks! Mind poking around other code you've worked on just to see if you notice any similar issues?

@diegoteran diegoteran merged commit bd4a846 into master Sep 22, 2023
5 checks passed
JL-Vidinoti pushed a commit to vidinoti/model-viewer that referenced this pull request Apr 22, 2024
* Convert to ThreeJS.Vector2 internally in public api.

Fixes google#4403

* Rename vector2D api interface

* Vector2DInterface consistency with Vector2D

* Update example to use u,v
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants