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

idea: three-mesh-ui, three-text-engine, and three-layout #12

Closed
trusktr opened this issue May 19, 2020 · 4 comments
Closed

idea: three-mesh-ui, three-text-engine, and three-layout #12

trusktr opened this issue May 19, 2020 · 4 comments
Labels
API change Suggestion for changing the API

Comments

@trusktr
Copy link
Contributor

trusktr commented May 19, 2020

The thought here is that the text layout/rendering engine (all stuff that happens within one rectangle area) could be its own standalone thing. Then the UI layout (ability to lay out boxes within boxes) could be a separate thing, and not only limited to boxes (imagine any 3D objects in a horizontal or vertical layout).

Actually, it could even be three things! three-layout-engine, three-text-engine, and three-mesh-ui. All three of them would be decoupled:

  • three-text-engine - defines how to render text in a rectangular area (on a plane)
  • three-layout-engine - defines layouts, basically like the current Block mechanism, but does not specifically render anything in the layout, it's just virtual spaces.
  • three-mesh-ui - this uses three-text-engine to create objects with text, creates planes (f.e. for the backgrounds), and then uses three-layout-engine to lay out the text and the planes.

Any other library could, for example, use just three-layout-engine to lay any objects out. F.e. imagine a row of spheres, with no planes.

The decoupling of the layout from what will be rendered within the layout would be very nice.

Of course, maybe this doesn't need to be three separate libs, and it can be one lib with all three parts within the lib. But thinking about the three separate parts is the main idea.


If I want to, for example, use the layout system with the current Blocks, how may I skip using the planes and instead put my own objects in there? I think currently I would have to traverse block.threeOBJ and manually remove what I don't want then stick in what I want.

With a layout decoupled, I could just use the layout API if I need to.


Instead of having three libraries, we could start by arranging src into three folders:

src/
  layout/
  text/
  ui/
  index.js

where ui/ would import from both layout and text, and index.js would re-export everything including the existing Block class, etc, but would also export new underlying layout and text classes.

@trusktr trusktr changed the title idea: this could be two libraries: three-mesh-ui and three-text-engine idea: three-mesh-ui, three-text-engine, and three-layout May 19, 2020
@felixmariotto felixmariotto added the API change Suggestion for changing the API label May 19, 2020
@felixmariotto
Copy link
Owner

This is really interesting.

In my opinion, whatever the separation we create, it should still live in one single repo, because it's pretty entangled: it would help working on only one part, or using only one part, but on another hand we don't want to complicate the lib usage for the majority of users (who I think will only want a quick tool to add a panel in their three.js project).

The other benefit I see here is that the user could plug in pre-made panels to their Blocks :

import { woodenPanel } from 'three-mesh-ui/ui/panels'

const block = ThreeMeshUI.Block({
  width: 2,
  height: 2,
  panel: woodenPanel
});

There would be a default panel used when the user didn't choose any.

@felixmariotto
Copy link
Owner

  • three-text-engine - defines how to render text in a rectangular area (on a plane)
  • three-layout-engine - defines layouts, basically like the current Block mechanism, but does not specifically render anything in the layout, it's just virtual spaces.
  • three-mesh-ui - this uses three-text-engine to create objects with text, creates planes (f.e. for the backgrounds), and then uses three-layout-engine to lay out the text and the planes.

Yes we should separate concerns. Howerver I feel that your three-mesh-ui block will overflow on three-text-engine with this separation model. I would modify it like so :

  • layout-engine (compute blocks inside blocks)
  • content-engine (takes container measurements, returns content like panel, and positioned glyphs)
  • text-renderer (as rendering glyphs is, as we saw, a vast field of various options, content-engine would fetch glyphs from text-renderer, that would not care about anything else than rendering glyphs)

content-engine could have a Text class, that would take a textType attribute. content-engine would only care about fitting glyphs of a given size inside a container. In parseParams (which should be renamed) and updateLayout, it would call the right text-renderer class methods, according to its textType attribute

Text should be in three-text-engine, as it should only care about positioning and scaling a rectangle, and calling functions of content-engine, that would in turn call functions of text-renderer

What do you think ?

This was referenced May 19, 2020
@trusktr
Copy link
Contributor Author

trusktr commented May 20, 2020

By "glyphs", do you mean a single character? What I imagine is that the text engine would worry about rendering text within a rectangle. If it were only rendering one character at a time, and then giving that to content-renderer (or whatever it will be called), my concern is that it may get complicated if one sentence (for example) is made of glyphs of varying type. In other words, it would be optimial that if a whole sentence is using MSDF (for example), then the whole sentence can be rendered as a single object; and I think that this aspect would live in the text renderer (f.e. including wrapping the sentence based on a given width).

But I'm not totally familiar with everything yet. Let me learn more. Maybe you are coming at it with a different perspective based on your knowledge of the whole thing.

Also it might be that per-character rendering is more possible with things like GeometryText, but maybe with VectorText (like the war and peace demo), that stuff would all render on a single quad, and otherwise it would be less efficient (in which case if rendering on a single quad I imagine the text renderer would handle that part for a given sentence or paragraph within a rectangle).

@felixmariotto
Copy link
Owner

I'm closing this, because it has been address by version 2.0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API change Suggestion for changing the API
Projects
None yet
Development

No branches or pull requests

2 participants