• Content Count

  • Joined

  • Last visited

About TMTH

  • Rank

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Just a few thoughts, unstructured, stream of consciousness style. 1. Working with primitives we have two very different areas – primitive transformations (all that matrix things) and primitive alignment (something to make developer’s life easier). On can leave without the latter, doing everything by hands, without any help from the framework, but not without the former. So, that transformation layer has to be stable and has to have very predictable behavior. Now, the framework has some problems with that predictable behavior. 1.1. Origin is not origin. Origin is the point (0, 0) in the coordinate system where our primitive is defined. It is natural to define primitive in its parent local coordinate system – we can define scale, rotation and translation inside the parent, based on parent’s origin point, and using translate * rotate * scale transformation we can place the primitive anywhere we like. That is not the case of Prim2DBase. 1.2 In search of underlying model Now I’ll try to reproduce the model as I managed to understand it during my evaluation of canvas2d: * Size of the primitive is specified with respect to local coordinate system of the parent, so scaling parent will scale child also, and setting child.size = parent.size will make child to fill the parent. No problems here. * Position of the primitive is specified in some kind of local coordinate system of the parent, with origin point moved to its bottom left corner. You can set parent’s origin to any value you like, it will not change child position. So, it is not the local coordinates of the parent – child positions ignore parent’s origin. And one more thing – position of the primitive is a vector, that corresponds to some point inside the primitive. And that point is not the origin of the primitive. And we can’t change it. And the only way to find that point is to read the docs or to try use it. * Rotation is specified in local coordinate system of a child, with respect to child’s origin. As I understand it, applying several rotations to primitive is not directly supported. If you want to create some rotation animation about arbitrary point (rotation2) of already rotated primitive (rotation1), you have to use two primitives. One with scale, position and rotation2 and another (child of first) with rotation1. * Scale. I give up here. I can’t understand the logic of scale (see PG for example From general considerations I see only two ways to apply scale – based on parent origin or based on child origin. Neither seems to be implemented (or it is, but with the current implementation of primitive position it’s hard to understand how it is working). 1.3 And … My current opinion is the following – the whole module is over-engineered, it lost the simplicity and logic of OpenGL transformations, and gained nothing in return. It’s easier for me to position thing using matrix transforms then to understand the logic of canvas2d. What I suggest is to refactor the system using the following principle – provide user with a simple way to do simple things, and let him do complex things any way he wants. One way to do it: State that Canvas2d – is 2D vector graphics library. Vector graphics is all about vectors and transformations. The framework does not have to hide that fact from user. Parent-child hierarchy has to be interpreted as coordinate systems hierarchy. Framework have to simplify some standard thing, providing some tools to deal with complex things. For example, in the pair of two primitives – parent and child, parent will have origin property, that will affect child primitives only. Every child will have scale, rotation and position properties that will be used to build most frequent transformation (translate * rotate * scale). For every other possible transformation, child provides method to add user defined transformation matrix, maybe providing some helper method. (child.addTransfrom(new RotationTransform(point, angle)). I warned that it would be a stream of consciousness 2. About primitive alignment First let say, that there are two very different kind of alignments – positioning (left, right, top, bottom, center) and fill-stretch. 2.1 Let’s talk about first group. May be I don’t understand something, but I see the problem in the following way – we have user defined scale and rotation transform, and we have to calculate translation transform by ourselves. And…where is the rocket science? 1. Take bounding rectangle of scaled and rotated primitive (AABB, in coordinates of parent), 2. Apply margin vector (+ to tr, - to bl) to get primitive effective rectangle, 3. Take parent primitive rectangle (AABB, in self coordinates) 4. Apply padding vector (+ to bl, - to tr) to get layout area 5. Calculate required translation (align one rectangle inside another) But if you take into account current implementation of origin/position things, you will get the rocket science. 2.2 Scale also have to be computed … oh my That’s all is only my opinion after more than a month of canvas2d evaluation. May be I just don’t understand something; may I don’t get the idea of the framework. But what I see now – canvas2d tries to hide the complexity of WebGL, but the abstraction used to do it is itself more complex than WebGL (in the part of transformations)
  2. I'm not sure that I understand your question. There are two kinds of positions - position of glyph in the source texture, and position of glyph in the target texture (or on screen). rectangle(x, y, x + width, y + height ) gives you rectangle in source texture, in absolute, not normalized coordinates - the glyph, that has to be rendered. On the other side, xoffset, yoffset, xadvance gives you directions on how to render that glyph in target. You need all of them - xoffset and yoffset to render current glyph, and xadvance to find base position for the next glyph. They've got a picture here
  3. @Nockawa, Yes, width is the width of the character, but you can't discard xadv because it defines position increment when moving from one character to the another. And yes, that increment is not equal to character width. Example is here
  4. "Origin property of primitive" is solved. About width and height. You are right, you can set it on sprite instance. As I said, that is not a bug, that is a question of usability.
  5. @Temechon, thanks. That solution will solve my problem.
  6. @Nockawa, that's not actually a bug. BitmapFontTexture is working properly. That was a question about using regular FontTexture "when using custom font, embedded into css/html ". So, when I have: @font-face { font-family: AAA } in my css, and refer to that AAA font in Text2D settings, font is not always loaded to the client when Text2D starts to render. So, text is rendered using some default browser substitute. The same thing can happen with ordinal html, but after loading the font browser usually re-renders text. And the question was - can we do something with it, or the only way to use custom font is to use bitmap font texture.
  7. Character width calculation is wrong for not mono-spaced fonts. Error is here (BMFontLoaderTxt._buildCharInfo): if (xadv) { width = xadv; } Character width is not always equal to xadv. Try to export Arial from BMFont and look to number characters (48-57) When rendering, wrong part of texture is taken for character. @Nockawa
  8. Sprite2D expects that underlying texture may not be loaded on sprite2d creation. It waits for texture to load, and everything is working fine. But the same problem can arise with Text2D, when using custom font, embedded into css/html. When Text2D object is created, it tries to create font texture, using supplied font parameter. But that font has to be loaded, and that is the process that takes time. So there is no font to use. In Firefox it leads to rendering Text2D objects without any text at all, soft page refresh fixes it. In Chrome one of the system fonts is used instead of required font. Soft page refresh doesn't not fix it, you have to recreate Text2D object. @Nockawa, is there any work around for this? UPD: One can use Bitmap font, that do know about loading time, and waits for underlying texture to load. But is that the only way to deal with the problem?
  9. That problem is more urgent then the first one. Because you can emulate CACHESTRATEGY_ALLGROUPS using CACHESTRATEGY_TOPLEVELGROUPS, just making fake "child" for group and manually setting it's position in response to "parent" actualPosition property changed. Thus you will have cached group, that behaves just like normal group. But when your turn on CACHESTRATEGY_TOPLEVELGROUPS using designSize, all your layout will be visually broken. And I can see no workaround for that problem.
  10. Here is PG. When using designSize on canvas alignment properties are unusable. There are two different use cases: 1. I manually position primitive on some point. I expect it's position to be uniformly scaled from design size to real rendering size. That one is working. 2. I do not position primitive, but I set primitive alignment. Let it be marginHAlignment = BABYLON.PrimitiveAlignment.AlignRight. In that case I expect this primitive to be stuck on the right side of the rendered canvas. That case is not working. So, building real UI I have a problem. I can build UI panels using absolute positioning, and it will be OK, but how can I position those panels? Suppose I want one panel to be on left side of the canvas, and one on the right side - not so complex high level layout. Left one will be positioned fine, but with positioning right one I will have a problem. Big one. @Nockawa, is there any work around for this?
  11. There is a question on using Sprite2D primitive when sprite size is larger then texture size. The common usage scenario is filling some area with "pattern" texture. Logically, that behaviour can be achieved by setting wrapU and wrapV properties of underlying texture to Texture.WRAP_ADDRESSMODE. But Sprite2D doesn't support that usage scenario. In Sprite2D constructor: super(settings); this.texture = texture; this.texture.wrapU = Texture.CLAMP_ADDRESSMODE; this.texture.wrapV = Texture.CLAMP_ADDRESSMODE; so, Sprite2D overrides texture settings. That snippet will use CLAMP_ADDRESSMODE, ignoring texture settings. tx.wrapU = Texture.WRAP_ADDRESSMODE; tx.wrapV = Texture.WRAP_ADDRESSMODE; let sprite = new Sprite2D(tx, ...); But if you really want to have WRAP_ADDRESSMODE, you can do as following: let sprite = new Sprite2D(tx, ...); sprite.texture.wrapU = Texture.WRAP_ADDRESSMODE; sprite.texture.wrapV = Texture.WRAP_ADDRESSMODE; And the sprite will be filled with texture. The workaround is fairy simple, but I want to know the logic behind that solution - texture settings override in constructor. @Nockawa
  12. Here is PG: case 1. I have primitive with default fill that is not null. When I try to change that fill (on click), everything is OK. case2. I have primitive with default fill that is null. When I try to change that fill (on click): case 2.1 if I use "BABYLON.Canvas2D.GetBrushFromString" to produce IBrush object nothing happens case 2.2 if I use "new BABYLON.SolidColorBrush2D" to produce IBrush object nothing happens, but second click will change the color. Is it a bug or designed feature? (@Nockawa)
  13. There are two questions about sprite2d behaviour, again I don't know whether it's bug or intended properties (fun club of @Nockawa keeps working) 1. Origin property of primitive. (That can be a bug) From documentation: Origin: define the origin of the primitive, default being 0.5,0.5, which is the center of the primitive, 0.0,0.0 would be the bottom/left corner of the primitive. The origin play a role in the rotation/scaling of the primitive but not in its positioning. Here is PG with exploration of that "not in its positioning" thing in the context of Sprite2D: As we can see, the right origin formula has to be written as "...but not in its positioning, if the primitive is not Sprite2d. In later case, you wouldn't guess the algorithm that derives actual sprite position from it's position and origin properties. 2. Size and width + height (That is a question of usability). Simple - you can set size property, but you can't set height and width properties on sprite2d. I belive that is the intended behaviour, because there are no height and width in sprite2d constructor settings, nor in renderablePrim2d or prim2dBase. But, 1. using all shape2d-based primitives and group2d you can set size or height/width, 2. on all primitives (including sprited2d) you can set position or x/y so, that is one of those nasty little things that you have to just remember.
  14. And one more bug (or feature that I don't understand) for @Nockawa I'm using designSize on canvas. When I change cachingStrategy on canvas, I see change in absolute position on top level primitive. Is it intended behaviour?
  15. Yes, I've read all the docs, and explored large part of canvas2d source code. I could suggest one improvement of documentation - strict marking of components that work now, and component that are under development. So, that one reading, for example, documentation on Group2D could see, that not all cache modes are supported right now