Draw a Line with a simple single colour fading gradient

I’ll put up what I have so far.

To function it requires a VR remote controller. The faded line and the marker will show up with a dummy model for the controller.

Created a fiddle here

https://jsfiddle.net/danrossi303/mrru53La/

Original wip demo here

http://dev.electroteque.org/vrcontroller/raycast.html

I don’t have any VR set, but…
Hmm… I see you add the laser marker to the object of the laser line. From this point, if I’m right, you have to transform the point of intersection from the world coordinate system to the laser line coordinate system. Take a look at .worldToLocal() method. Notice, that this method updates the vector you’ve passed to it and doesn’t create a new one.

And I didn’t get that part in your code:

 function setSelectedObject(intersection) {

// . . . not so interesting code is omitted :)

   if (laserLine) {
     var linePosition = laserLine.geometry.attributes.position.array,
     markerPosition = laserMarker.geometry.attributes.position.array; // this is not the position of the marker, but its geometry's vertices

     linePosition[5] = intersection.point.z;
     markerPosition[3] = intersection.point.z;

     laserLine.geometry.attributes.position.needsUpdate = true;

   }
 }

Inside if, try it like that:

   if (laserLine) {

     var localPoint = new THREE.Vector3();
     laserLine.worldToLocal(localPoint.copy(intersection.point));
     laserLine.geometry.attributes.position.setXYZ(1, localPoint.x, localPoint.y, localPoint.z);
     laserMarker.position.copy(localPoint);

     laserLine.geometry.attributes.position.needsUpdate = true;

   }

I’m experimenting adding to the controller object or the line object. I tried copying the position from the point and it displayed the same.

The laser line moves with the parent object and so does the marker. I just need to change the distance. And its this detected distance I just need to change I presume.

Could I get a local point from any of this , which is used to set the raycaster ?

tempMatrix.identity().extractRotation( controller.matrixWorld );
raycaster.ray.origin.setFromMatrixPosition( controller.matrixWorld );
raycaster.ray.direction.set( 0, 0, -1 ).applyMatrix4( tempMatrix );

Then you can use .distance property of intersection object for z value of the second point of the line, and the same for the position of the marker.

Kind of:

laserLine.geometry.attributes.position.setZ(1, intersection.distance);
laserMarker.position.z = intersection.distance;

And this

could be like that:

controller.getWorldPosition(raycaster.ray.origin);
controller.getWorldDirection(raycaster.ray.direction);
1 Like
laserLine.geometry.attributes.position.setZ(1, -intersection.distance);						
laserMarker.position.z = -intersection.distance;

This seems to work. Have to add a negative value. A positive number the line reverses.

The scale has to be modified to suit the change in distance but I think I made code for that.

I’ve updated the distance code. The marker seems to cut through the box so not stay in front of it. It’s partially visible now however.

https://jsfiddle.net/danrossi303/mrru53La/1/

I’ve borrowed some offset code from another project. If moving the controller it still cuts through the box but stays in front.

There is still the problem with the circle scaling when the distance changes and needs to stay the same size.

var distance = intersection.distance;
distance -= intersection.object.geometry.boundingSphere.radius;
laserMarker.position.z = -distance;

https://jsfiddle.net/danrossi303/mrru53La/2/

About keeping the same size regardless of the distance, take a look at this SO answer and its jsfiddle exmaple.

Hi sorry about the late response. I was unable to successfully dynamically generate the scale.

This is an example of rescaling the marker with a static value of 0.035.

This is the best I can get that matches what I need. I only found two examples out there and both have generated wrong values. The marker is very large not reduced in size.

We have success with the faded line shader thanks. And I had to wrestle getting the marker actually in front of the object not inside it with extra distance offset using the boundingsphere radius

although moving the VR controller the marker will intersect inside the object still due to head movement.

But this scaling I might need to make dynamic not static ?

https://jsfiddle.net/mrru53La/3/
https://dev.electroteque.org/vrcontroller/raycast.html

I have yet to test it but I believe my calculation may be correct. To rescale the marker from the measured raycaster distance

It would be defaultScale / defaultZ * rayCasterDistance .

So 0.07 / 10 * 4 etc.

this gives me a value near the static value of 0.035.

Took a bit of thought. No need for too much code there.

I’ve updated my full findings with scaling marker here no with a fiddle. That calculation is working

https://discourse.threejs.org/t/laser-and-marker/1851/2?u=danrossi