cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - If community subscription notifications are filling up your inbox you can set up a daily digest and get all your notifications in a single email. X

Orient the direction of a 3D arrow according to the camera

aletenti2
12-Amethyst

Orient the direction of a 3D arrow according to the camera

Hi,

I would like to ask the community if there is a way to orient a 3D arrow following the direction of the camera.

I mean, I have already obtained the eyepos, eyedir & eyeup values. I know how to use eyepos, but I don't know how to use eyedir & eyeup values in order to give an arrow the right direction.

Currently, what I have built is a test project with 2 views:

1) a view used from a mobile device that every second send to Thingworx eyepos values.

2) a view used in preview mode on a laptop that gets the eyepos values from Thingworx and gives these values to a 3D moving gauge, simulating the position of the mobile device in the area.

But this 3D gauge is in billboard mode, so it's always showing his main face.

I would like to transform this billboard gauge into a rotating arrow pointing the direction of the camera.

 

Any ideas?

3 REPLIES 3

Hi @aletenti2 ,

I think this is only a problem of calculation when you have aready  the position of the device and the eye vector from the tracking event.

So when you have an arrow which is directly aligned with the view then possible you do not have from this a more value , because you will see only the tail of it - so some circle on the screen. Therefore possibly it will be better to have the arrow alligned with the xz plane - so this  means to rotate around the Y axis in view direction and possibly to adapt the height of the arrow part  in Y direction.

My approach here is simple. I will set the position in view direction (adding the eye position to the eye direction vector with scale) and will rotate around Y something like this:

//// define camera tracking Event 
tml3dRenderer.setupTrackingEventsCommand (function(target,eyepos,eyedir,eyeup) {
 
   
 $scope.eye_dir[0] =  eyedir[0].toFixed(2);
 $scope.eye_dir[1] =  eyedir[1].toFixed(2);
 $scope.eye_dir[2] =  eyedir[2].toFixed(2);
     
  //model-2
  var scale=$scope.app.params.distScale;
 $scope.setWidgetProp('model-2',  'x', ( eyepos[0]+eyedir[0]*scale));
 $scope.setWidgetProp('model-2',  'y', ( eyepos[1]+eyedir[1]*scale));
 $scope.setWidgetProp('model-2',  'z', ( eyepos[2]+eyedir[2]*scale));
  
  
  let vecDirXZ=[]
  vecDirXZ[0]=eyedir[0]
  vecDirXZ[1]=0.0
  vecDirXZ[2]=eyedir[2]
  vecDirXZ=$scope.vec_normilize(vecDirXZ)
  vecDirZ=[0.0,0.0,-1.0]
  let dotP1= $scope.dot_product(vecDirXZ,vecDirZ)
  console.log("dotP1=",dotP1)
    $scope.setWidgetProp('label-1',  'text',"dotP1="+String(dotP1.toFixed(3)))
  let angleY=0
if ( vecDirXZ[0] < 0.0 )
    angleY= 180*Math.acos(dotP1) / Math.PI;
  else
    angleY=  0- 180*Math.acos(dotP1) / Math.PI;
  //--------------
   $scope.setWidgetProp('model-2',  'ry',angleY)
  $scope.$applyAsync()
  })   
////////////////////////////////////////////////////

where the used  math function (some math basics are defined as:

////////////////////////////////////////////////////////////////////////
$scope.dot_product=function(ary1, ary2) {
    if (ary1.length != ary2.length)
        throw "can't find dot product: arrays have different lengths";
    var dotprod = 0;
    for (var i = 0; i < ary1.length; i++)
        dotprod += ary1[i] * ary2[i];
    return dotprod;
};

///////////////////////////////////////////////////////////////////////////////////////////////
/// the length of a vector
$scope.vec_len=function(ary1) {

    var len = 0.0;
    for (var i = 0; i < ary1.length; i++)
       len += Math.pow(ary1[i],2);
    return Math.sqrt(len);
};

///////////////////////////////////////////////////////////////////////////////////////////////
$scope.vec_normilize=function(ary1) {
ret=[];
  var len=$scope.vec_len(ary1);
  for (var i = 0; i < ary1.length; i++)
   ret[i]=ary1[i]/len;
  return ret;
  };


///////////////////////////////////////////////////////////////////////////////////////////////

Then tested and have this behavior on IOS - IPad device:

2023-07-11_13-01-41.jpg

Hello Roland, could you please share the whole project? I think it's a piece of code and something is missing.

Thanks!

Hi @aletenti2,

thanks for the feedback. There is no much more code - only the code what will call the definition on start event. But, yes there is not problem to share the project where I tested this . Actually I forgotten  to share to the last post , because this was only a project created with the goal to test this problem. So hope that it is helpful - attached the project now.

Announcements

Top Tags