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

TextGeometry changes and support in editor #27931

Open
wants to merge 11 commits into
base: dev
Choose a base branch
from
Open

Conversation

zz85
Copy link
Contributor

@zz85 zz85 commented Mar 16, 2024

Related issue: maybe

Description

Add text geometry support to three.js editor

image

** details **

  • add support for TextGeometry in editor. currently this is linked only to a single font, but all of TextGeometry functionality is wired to the editor's sidebar UI, which I think is more than sufficient now
  • depreciating height parameter in TextGeometry options for depth for consistency with ExtrudeGeometry, which refers to the thickness the Text will be extruded. using height is still supported but will emit a warning in the console
  • also added a scale parameter in TextGeometry and editor. The numbers that work well for font sizes is unusally large in three.js objects (esp in VR), so passing 0.01 makes it more the conversion more pleasant to work with
  • Serialization and deserialization works. toJSON() and fromJSON() is added to TextGeometry. I have to add this to Geometries.js for scene loading to work automatically in editor, but the dependency of an addon (TextGeometry is addon, ExtrudeGeometry is core) seems a little strange. Either there's a better way to extend the supported Geometries deserialization list or perhaps move TextGeometry out of the examples

This contribution is funded by blurspline

- add support for TextGeometry in editor. currently this is linked
  only to a single font, but all of TextGeometry functionality is
  wired to the editor's sidebar UI, which I think is more than
  sufficient now
- depreciating `height` parameter in TextGeometry options for `depth`
  for consistency with ExtrudeGeometry, which refers to the thickness
  the Text will be extruded. using `height` is still supported but
  will emit a warning in the console
- also added a `scale` parameter in TextGeometry and editor. The
  numbers that work well for font sizes is unusally large in three.js
  objects (esp in VR), so passing 0.01 makes it more the conversion
  more pleasant to work with
- Serialization and deserialization works. toJSON() and fromJSON()
  is added to TextGeometry. I have to add this to Geometries.js
  for scene loading to work automatically in editor, but the dependency
  of an addon (TextGeometry is addon, ExtrudeGeometry is core) seems
  a little strange. Either there's a better way to extend the supported
  Geometries deserialization list or perhaps move TextGeometry out of
  the examples
Copy link

github-actions bot commented Mar 16, 2024

📦 Bundle size

Full ESM build, minified and gzipped.

Filesize dev Filesize PR Diff
672.7 kB (166.7 kB) 672.8 kB (166.7 kB) +118 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Filesize dev Filesize PR Diff
452.4 kB (109.2 kB) 452.4 kB (109.2 kB) +0 B

editor/js/Strings.js Fixed Show fixed Hide fixed
editor/js/Sidebar.Geometry.TextGeometry.js Fixed Show fixed Hide fixed
@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 18, 2024

It seems it is not possible to save/reload a text mesh. The missing serialization/deserialization support was the main reason why TextGeometry was not added to the editor yet.

Since TextGeometry and Font are no classes in the core, ObjectLoader can't process them. Meaning the editor needs a separate logic to store and restore text geometries.

When serialize/deserialize instances of geometry generators, their type should be retained. Meaning if you serialize an instance of BoxGeometry, you do not end up with BufferGeometry after the deserialization but BoxGeometry. Doing the same for TextGeometry requires the storage of fonts though.

@zz85
Copy link
Contributor Author

zz85 commented Mar 18, 2024

@Mugen87 - threejs builds are not updated in his PR which is why the Text geometry serialization/deserialization is not working in linked example is because the

The new TextGeometry .toJSON and .fromJSON should allow all of these to work like you described. (The font definitions are also serialized).

I'll push the builds in the next commit.

@zz85
Copy link
Contributor Author

zz85 commented Mar 18, 2024

it appears the previous rawgit link is cached, but using this link should show TextGeometry persisting and loading from IndexedDB across refreshes.

https://rawcdn.githack.com/zz85/three.js/33a29ddc4c1d3133d2e4082005f789d3269ed0b4/editor/index.html

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 18, 2024

The new TextGeometry .toJSON and .fromJSON should allow all of these to work like you described. (The font definitions are also serialized).

@zz85 Thanks, I've totally overlooked the changes to TextGeometry!

@zz85
Copy link
Contributor Author

zz85 commented Mar 19, 2024

changes from core Geometries now moved to

loader.registerGeometry( 'TextGeometry', TextGeometry )

https://rawcdn.githack.com/zz85/three.js/e646d485f0bcc2099ac2736f734231cb84f8ea6b/editor/index.html

Add `@deprecated` annotation, update warning text.
@@ -35,7 +36,15 @@ class TextGeometry extends ExtrudeGeometry {

// translate parameters to ExtrudeGeometry API

parameters.depth = parameters.height !== undefined ? parameters.height : 50;
if ( parameters.depth === undefined && parameters.height !== undefined ) {
Copy link
Collaborator

@Mugen87 Mugen87 Mar 19, 2024

Choose a reason for hiding this comment

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

This PR does two things in one go. It adds support to the editor and renames the height parameter to depth.

Ideally, there is a single PR for each change since both changes are independent of each other.

Besides, if height is renamed, the example code (meaning webgl_geometry_text.html and others) should be updated in order to avoid deprecation warnings.

That said, I also favor depth since height was a confusing name for describing the thickness (or depth) of the text.

Would you be okay with moving the renaming change to a separate PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure I can do that. I'll wait on the confirmation of the loader.registerGeometry() api before making the changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

actually the change to extract is easier to do, so it's in #27949

@Mugen87 Mugen87 added this to the r163 milestone Mar 19, 2024
@@ -261,6 +263,12 @@ class ObjectLoader extends Loader {

}

registerGeometry( type, klass ) {
Copy link
Collaborator

@Mugen87 Mugen87 Mar 19, 2024

Choose a reason for hiding this comment

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

@mrdoob Are you okay with this kind of new interface?

This approach is in general interesting since it could be used in context of other classes like materials as well. Meaning custom/addon materials implement a static fromJSON() (factory) method that ObjectLoader/MaterialLoader can use to create an instance. The internal material lib can be enhanced via:

loader.registerMaterial( 'MeshGouraudMaterial', MeshGouraudMaterial );

Related #21265, #11266.

Copy link
Owner

Choose a reason for hiding this comment

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

It's interesting indeed...

I'd rename this.Geometries to this.geometryTypes though.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I have updated ObjectLoader manually but there still seems to be a diff in build/three.cjs.

Apart from that, the PR looks good to me!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated a merge from mrdoob/dev so there should be no conflicts now

@zz85
Copy link
Contributor Author

zz85 commented Mar 26, 2024

I'll be out for the next week or so, so I removed the builds for this branch have it caught up with mrdoob/dev - just in case this PR be merged as it is without further changes to the API

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 26, 2024

so I removed the builds for this branch

It seems there is still a diff though.

@mrdoob mrdoob modified the milestones: r163, r164 Mar 27, 2024
@zz85
Copy link
Contributor Author

zz85 commented Mar 28, 2024

It seems there is still a diff though.

sorry about that, should be fixed again

Mugen87 and others added 2 commits April 4, 2024 10:49
@mrdoob
Copy link
Owner

mrdoob commented Apr 5, 2024

Screenshot 2024-04-05 at 7 53 34 PM

Very cool!

How are we going to handle different fonts? Is it just a matter of adding the UI for it in the editor?

@zz85
Copy link
Contributor Author

zz85 commented Apr 6, 2024

How are we going to handle different fonts? Is it just a matter of adding the UI for it in the editor?

The easiest way to support different fonts as it is today is to have a fonts dropdown list which all the typeface fonts in the examples directory could be loaded by FontLoader when needed.

The more comprehensive approach might be to have Editor keep a registry of all fonts, also allowing the user to drag and drop fonts (including ttfs).

The serialization format in TextGeometry in this PR current state json-ify the entire font for convenience. I think it makes it easy for deserialization, but the approach to optimize for space would be to serialize fonts separately, then have TextGeometry look up the font database say via uuid.


if ( scale !== undefined ) {

this.computeBoundingBox();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is the bounding box computed at this point? It will be automatically recomputed when calling BufferGeometry.scale()?

Copy link
Collaborator

Choose a reason for hiding this comment

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

BTW: Is the introduction of a scale parameter really necessary? Couldn't apps just use Object3D.scale instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the reason to do it here is getting a scaled down (0.01) geometry mostly for connivence to be used in Editor.

the object.scale could be used, but I wasn't sure if it was a good idea to insert a TextGeometry at a custom object scale, hence having it in the geometry seems like a more convenient way.

Copy link
Collaborator

@Mugen87 Mugen87 Apr 10, 2024

Choose a reason for hiding this comment

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

In order to keep the parameters of TextGeometry to a minimum, it would be better to use Object3D.scale and not introduce an additional way for transforming geometry, imo.

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 22, 2024

I've noticed today that similar to #28187, published scenes with TextGeometry won't work because the required modules are not bundled in exported app.

@zz85
Copy link
Contributor Author

zz85 commented Apr 25, 2024

hmm, could we then just export addons by default, or exported them if TextGeometry is used?..

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 25, 2024

#28187 tried to conditionally add addons, imports and initialization code to published apps depending on the addon usage but I'm unsure about the implementation, tbh.

@mrdoob mrdoob modified the milestones: r164, r165 Apr 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants