mml-io / mml

Metaverse Markup Language
https://mml.io
MIT License
120 stars 13 forks source link

m-frame load-range and bounds (#59) #155

Closed MarcusLongmuir closed 5 months ago

MarcusLongmuir commented 5 months ago

Resolves #59

This PR adds both bounds and load range to the m-frame element.

Bounds

Adding bounds to m-frame means that remote content can now be included with the optional limitation that it be constrained to a specified area.

This has an impact on almost all elements because they are now tested against the bounds of an ancestor m-frame if one exists and clipped if any part of their bounds exceeds the frame (or if they have no bounds then their origin point is outside the frame)

This means that if their content bounds causes them to be clipped:

The bounds are specified as min-x, max-x, min-y, max-y, min-z, max-z with the origin of the m-frame being zero. This method of pairs for each axis allows for a likely common case where it is desirable to specify that an m-frame's origin is the lowest point of the content, but that the allowed content height is from 0 to n with e.g. min-y="0" max-y="10". Only specifying a single value for each axis would not allow this.

Example

<m-plane color="white" width="2000" height="2000" rx="-90"></m-plane>
<m-light type="point" ry="45" rx="65" rz="-45" x="10" y="10" z="10"></m-light>
<m-cube y="0.5" id="my-cube" color="red"></m-cube>

<m-frame
    debug="true"
    min-x="-3" max-x="3"
    min-y="1" max-y="4"
    min-z="-3" max-z="3"
    src="https://public.mml.io/duck.glb"
>
  <m-model src="https://public.mml.io/duck.glb" y="2" debug="true">
    <m-attr-anim attr="x" start="-4" end="4" duration="5000"></m-attr-anim>
  </m-model>
</m-frame>

https://github.com/mml-io/mml/assets/669895/bf72a64d-532e-424f-b658-b37922e9ac38

Load Range

The (load-range) of an m-frame allows specifying the distance from the m-frame that the user should be before the content is loaded. There is also an additional attribute (unload-range) to specify how far the user can then return outside that range before the content is unloaded. Using this unload-range attribute avoids cases where the content would otherwise potentially be loaded and unloaded rapidly if the user moved along the border defined by the load-range.

This functionality can be combined with bounding the m-frame such that the range is the distance from the bounds. E.g. If the min-x="-3" load-range="7" then the effective range from the origin of the frame in x is 10. The debug visualisation in the below example should help explain this more clearly:

Example

<m-plane color="white" width="2000" height="2000" rx="-90"></m-plane>
<m-light type="point" ry="45" rx="65" rz="-45" x="10" y="10" z="10"></m-light>
<m-cube y="0.05" height="0.1" id="my-cube" color="black"></m-cube>

<m-frame
    debug="true"
    src="https://public.mml.io/rgb-cubes.html"
    min-x="-3" max-x="3"
    min-y="0" max-y="4"
    min-z="-3" max-z="3"
    load-range="7"
    unload-range="5"
>
</m-frame>

https://github.com/mml-io/mml/assets/669895/d1273db8-c60f-4779-9947-5eee5e92e2a0


What kind of changes does your PR introduce? (check at least one)

Does your PR introduce a breaking change? (check one)

If yes, please describe its impact and migration path for existing applications:

Does your PR fulfill the following requirements?