xml3d / xml3d.js

The WebGL/JS implementation of XML3D
Other
75 stars 25 forks source link

Feature: Projected object locations #13

Open wherget opened 11 years ago

wherget commented 11 years ago

From CSSOM, HTMLElements have

partial interface HTMLElement {
  readonly attribute Element offsetParent;
  readonly attribute long offsetTop;
  readonly attribute long offsetLeft;
  readonly attribute long offsetWidth;
  readonly attribute long offsetHeight;
};

It would be very convenient if XML3D could provide these as well for scene elements. (Think text flow around single objects, positioning of supporting 2D content alongside, etc.) The values could be calculated by performing a projection calculation on the bounding box, for example.

lachsen commented 11 years ago

Those properties make sense for HTML, as they directly correspond to the 2D layout positioning. If we use the same properties for 3D, it makes sense to extend them for 3D space, e.g. you would also have offsetFront and offsetDepth or something like that.

We could also keep those properties in 2D space and make it relative to the current view point, but I don't think such a feature would be particular useful. Is there any specific usecase for this?

wherget commented 11 years ago

While I didn't check the specifics, I guess knowing the layout-relevant extents of an object would be relevant for tooltips, such as Tipped or simply Bootstrap Popovers. I already had two projects where I needed to hack the extent calculation myself (well, in the second one I just recycled it, fortunately it still worked...) for just that. Of course, extents should then be viewpoint specific for this use case. I'm not sure on how to extend the semantics of this into 3D, especially it's not clear to me how the latter would differ from the "plain" bounding box that's already available.

lachsen commented 11 years ago

Note that offset values in HTML are (as far as I know) independent of the 'viewpoint' (e.g. the current scroll position). Thus I'd avoid to make offset values of XML3D depending on the camera.

If it is about placing 2D labels on top of the 3D scene, I'd suggest to implement corresponding helper methods inside the <xml3d>, maybe even each individual scene graph element (group or mech) element. There is already a way to get the global bounding box. What we need is to extract a 2D box from a Bounding box considering the current view point. In addition, we might want to have a separate method to check occlusion. Having both of these methods, it should be simple to place labels on top of 3D content.

Don't we have already something like this implemented?

I see the issue that offset values like these won't work well with jquery, However, I also think jquery stops working in this respect when you start transforming and rotating Webpage content with css 3D transformations (e.g. try to get the offset an element that is scaled / rotated etc. by a parent element via css transform).

wherget commented 11 years ago

Indeed in HTML, these are independent of the viewport. However, XML3D being a "web content" format, my feeling is that treating the XML3D canvas as yet another viewport insde the webpage would be inconsistent. My thought experiment went along those lines: A plain XML3D scene in a web browser is by itself (without any supporting code) static_. As such, the elements visible should behave just as "regular" 2D elements, and web developers will want to use them as such. Popups being only one application, if as a plain old web developer I can't just say $("#some_geometry").popover("do what I mean"); I'd probably turn my back and never look at this again. I agree that it "should be simple" to do it with helper methods in <xml3d />, but why put it there, if one _could* make it so existing mechanics work as expected?

I'll investigate on the handling of regular and CSS-3D-transformed 2D content and report back.

*static in the sense that it will render as an image, unless I explicitly manipulate e.g. Xflow input parameters; BTW, does Xflow have a time-based operator?

lachsen commented 11 years ago

No, Xflow doesn't have any time based operators, so yes, an XML3D scene without JS is static.

I see your point with that specific example. However, another Web developer might want to use offset values to place 3D content relative to another element inside the XML3D scene. Though, if I think about it, we can extract the same information using bounding boxes of parent and child, or analyzing the local transformation. (and with the 3D layout options in XML3D, it's hard to use 3D offsets in the first place).

So maybe it makes more sense to interpret offset values of all XML3D element only in 2D and relative to the parent XML3D element. At least that would allow us to use jquery as expected. I would still be inconsistent compared to how offets work in relation to CSS transforms, I think.

wherget commented 11 years ago

If I'm completely honest, I think that the handling of offset* w.r.t. CSS transforms is bad as well. The CSS transform specification says that the bounding box is the border box for each element. offset* therefore just gives you a bounding box, which is probably not the minimal bounding box you would want. This leads to simliarly weird hacks such as this which are also not cross-broswer.

Why not do things better? To me, it feels more correct to set offset* to the minimal bounding box. It might be sensible to add those fields via a getter (& caching) such that it is only computed on demand, if it's too much of an effort to update those values vor every element all the time.

The purely 3D problem you sketched seems to be covered pretty well by what the current (purely 3D) Bounding Box and Transform API (i.e. getBoundingBox() and the <transform> element) offers.

In the course of adding offset*, it would be sensible to have getBoundingClientRect() do sane things as well, maybe one can be implemented on top of the other.