Skip to content

Instantly share code, notes, and snippets.

@andreasplesch
Last active April 21, 2019 18:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andreasplesch/33016fd0918178f5dfcf4632d477f4e4 to your computer and use it in GitHub Desktop.
Save andreasplesch/33016fd0918178f5dfcf4632d477f4e4 to your computer and use it in GitHub Desktop.
X3D 1D PlaneSensor on edge issue

Drag the red cone

This scene illustrates the difficulty of using a PlaneSensor when the view is parallel to the tracking plane (light blue). Dragging works well in the default view normal to the tracking plane. Press PgUp to change the viewpoint to an on edge view. Dragging cannot work because the intersection of the bearing with tracking the plane becomes ill defined.

https://bl.ocks.org/andreasplesch/33016fd0918178f5dfcf4632d477f4e4 https://gist.github.com/andreasplesch/33016fd0918178f5dfcf4632d477f4e4

Introduction prose

This spec. comment is the first of two proposed enhancements to PlaneSensor. The comments can be separated because the enhancements are not interdependant. This first comment concerns certain pathologies and the already recognized role of PlaneSensor as a line sensor. It requires a only modest amount of additional prose.

Issue prose

PlaneSensor has a few pathologies inherent to its functioning using intersections of the bearing with the tracking plane. These intersections are not always well defined. Two such situations are recognized:

   A) Dragging starts with the pointer located in the view frustum but ends with the pointer outside the view frustum, and typically outside the browser rendering surface.

   B) The intersection of the bearing with the tracking plane becomes ill defined because the bearing and the tracking plane are parallel to each other or close to it.

There is a need to define graceful browser behaviour for these situations. Here are suggestions:

   ad A) Once the pointer leaves the view frustum, the browser should act as if dragging continues with the pointer still being located at the edge of the view frustum at the point of exit. If then the pointer returns to the view frustum while still indicating dragging continues. If the pointer stopped indicating, dragging stops at the exit point and the corresponding events are generated. Alternative resolutions may include unconditionally stopping the dragging process when leaving the view frustum.

   ad B) In this case, unless in linse sensor mode, dragging is disabled, eg. the node behaves as if the enabled field is false. The browser may generate a notification. It is left to the discretion of the browser at which angle between bearing and tracking plane their intersection is considered ill defined, or too sensitive to changes in bearing.

The remainder of the comment address the line sensor mode case.

The current spec. language recognizes that PlaneSensor can play the role of a line sensor with this sentence at the end of the 7th paragraph in section 20.4.2 :

"This technique provides a way to implement a line sensor that maps dragging motion into a translation in one dimension."

The outlined technique works well in most cases. The clear user expectation for line sensor mode is that as long as the sensed line is visible, dragging along the line with the pointer should work. The issue is that a line sensor geometry should still be draggable when the bearing is parallel to the tracking plane, eg. the tracking plane is viewed on edge. This case cannot be considered a pathology since the line is still fully visible, and a user would not be aware of the existence of a tracking plane. However, the intersection of the bearing with the tracking plane becomes ill defined, and therefore neither an initial intersection point nor a subsequent intersection point can be determined.

The linked X3D scene illustrates (https://bl.ocks.org/andreasplesch/33016fd0918178f5dfcf4632d477f4e4 ). The thin red cone is used as a line sensor, with the X dimension constrained to 0, and the Y dimension unconstrained but clamped to [-5,5]. The tracking plane is the default XY plane and is visualized as a thin, transparent, blue plate. There are two included Viewpoints: A) default (along Z), and B) along X. Dragging the cone from Viewpoint A works since intersections with the tracking plane are well defined. Dragging the cone from Viewpoint B is still expected to work since it is fully visible and the user is not aware of the existence of a tracking plane, nor should she be expected to be. However, dragging cannot work well since intersections become ill defined. Indeed, many tested X3D browser follow the spec. and therefore cannot address this case as it involves an ill defined intersection. Some X3D viewers already reinterpret the spec. and ignore the XY tracking plane in this case to allow proper dragging. The mismatch in browser behavior points to a need to refine the spec.

Solution prose

The on edge issue can be addressed if browsers are free to determine a more suitable tracking plane than the XY plane. A suitable tracking plane is one which is not parallel to the current bearing, and therefore can be intersected, and also contains the unconstrained axis (X, or Y as in the example) of the local sensor coordinate system. A free choice of tracking plane may be specified by adding only a few sentences to paragraph 7:

" ... This technique provides a way to implement a line sensor that maps dragging motion into a translation in one dimension. In this case, the browser is free to choose any plane that contains the unconstrained axis (X or Y of the local sensor coordinate system) as a tracking plane. A browser is therefore able to determine a tracking plane which can be robustly intersected with the initial bearing, a necessity for situations where the default XY tracking plane is subparallel to the bearing."

trackPoint_changed discussion

The trackPoint_changed event provides the unclamped intersection of the bearing with the tracking plane. However, if the determination of a tracking plane is left to the discretion of the browser in the line sensor case, trackPoint_changed will vary between implementations. Two resolutions are proposed.

trackPoint_changed resolution

For the line sensor case, the trackPoint_changed event could explicitly become undefined, and declared not portable between between browsers. After all, generally in 3d two lines (the bearing and the sensed line) do not intersect.

Suggested prose:

"In line sensor mode, the trackPoint_changed event is undefined. It is recommended that the event value is a point on the sensed line close to the pointer position."

An alternative resolution may be to redefine the trackPoint_changed event specifically for the line sensor case. The trackPoint position could then be defined as a point on the sensed line, similarly to how trackPoint_changed is a point on the sensed plane in plane sensor mode. It could be defined as the sum of a computed relative translation vector and the initial intersection point. For this purpose the relative translation vector, to the initial intersection, without the added offset, is fixed to the constrained dimension (x = 0 in the example) and unclamped in the variable dimension (Y in the example). Also, the relative translation vector's z component (in sensor local coordinates) is zeroed. These operations have the overall effect of placing the track point on the sensed line near the indicated pointer location, independant of the browser's choice of tracking plane orientation.

This is attractive since the definition is consistent with plane sensor mode where trackPoint_changed is effectively the sum of the unclamped relative translation vector and the initial intersection point. Although the redefinition for line sensor reads complicated, it just adds clamping of the point onto the sensed line, compared to the plane sensor definition.

Suggested prose:

"In line sensor mode, the trackPoint_changed event is redefined. It is then the sum of the initial intersection point and a partially clamped, relative translation vector. The partially clamped, relative translation vector is the relative translation vector, without the additional offset, clamped to the value of the equal components in the constrained dimension and unclamped in the variable dimension, with a zeroed z component. As such, the trackPoint_changed position will be located on the sensed line close to the pointer."

Implementation

freeWrl, x_ite and x3dom (see below) have implementations of the suggested line sensor behaviour:

https://bl.ocks.org/andreasplesch/raw/15ca27439fde2a6a721fbc36d667ea15/

Related

http://www.web3d.org/x3d/content/X3dTooltips.html#PlaneSensor

<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script type="text/javascript" src="https://www.x3dom.org/download/dev/x3dom-full.debug.js"> </script>
<link rel="stylesheet" type="text/css" href="https://www.x3dom.org/download/dev/x3dom.css">
<title>X3D PlaneSensor 1D on edge issue</title>
</head>
<body>
<div id="content">
<x3d width='600px' height='400px'>
<scene>
<inline url='PlaneSensor1DOnEdge.x3d'></inline>
</scene>
</x3d>
<button onclick='doclick()'><h2>click to change view</h2></button>
</div>
</body>
<script>
function doclick() {
var rt = document.querySelector("x3d").runtime;
rt.nextView();
document.querySelector('h2').textContent = rt.viewpoint()._vf.description;
}
</script>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<X3D>
<Scene>
<Viewpoint description='A-default' />
<Viewpoint description='B-alongX' position='10 0 0' orientation='0 1 0 1.57' />
<!--Viewpoint description='B-alongY' position='0 10 0' orientation='1 0 0 -1.57' /-->
<Shape DEF='trackingPlane'>
<Appearance><Material transparency='0.8' diffuseColor='0.0 0.0 1.0'></Material></Appearance>
<Box size='5 5 .04' />
</Shape>
<Transform DEF='PlaneSensorContainer'>
<PlaneSensor DEF='PS' minPosition='0 -5' maxPosition='0 5' />
<Transform DEF='ConeMover' rotation='0 0 1 0'>
<Shape DEF='trackingPlane'>
<Appearance><Material diffuseColor='1.0 0.0 0.0'></Material></Appearance>
<Cone height='2' bottomRadius='0.3'/>
</Shape>
</Transform>
</Transform>
<ROUTE fromNode='PS' fromField='translation_changed' toNode='ConeMover' toField='set_translation'/>
</Scene>
</X3D>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment