Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X
I want to translate a model in Y direction using javascript but is not able to do so. I tried a method given by Roland Raytchev in this link https://community.ptc.com/t5/Vuforia-Studio/3D-object-movements-using-JavaScript/m-p/592546#M5001
but was not able to do so. I also tried quadcopter example but due to lack of coding experience was again unable to do so.
Any help would be appreciated.
Solved! Go to Solution.
Hi @vivekse
I think JavaScript expression in your project is not quite correct !
$scope.moveOnYAxis = function() {
$scope.setWidgetProp( "model-1", "ty", $scope.getWidgetProp( "model-test", "ty") + 1.0);}
>> the following problems:
1.) translation axis coud be "x", "y" and "z" and rotations respectively "rx", "ry" and "rz" -> property “tx" does not exist
2.) so far I know we have setWidgetProp but we do not have getWidgetProp !
You need to use the syntax $scope.view.wdg[WidgetName][propertyName] instead
Another problem is that this code will have as result a jump. But so far, I understand you need continuous movement. Right?
A correct approach could be this one (add this code 1:1 in your project Home.js) :
/////////////////// function translateOnAxis definition with arguments
//function Arguments:
// WidgetName --> e.g. "model-1"
//Axis --> could 2x", "y" or "z"
//distance --> in meter m=1 is 1meter
//speed --> in meter per second
///////////////// translateOnAxis function body
$scope.translateOnAxis = function(WidgetName,Axis,distance,speed) {
var debug=false; // when true prints in the console but make slow!
var interval = 0.05*speed // distance for 0.05 sec
var count=0;
var ready = false;
//=== loop for the movement
for(v=0;v< distance;v+=interval)
{count++ // this counts the step
let movedDistance=($scope.view.wdg[WidgetName][Axis]+ interval*count)
//check if we arrieved on the final destination
if (movedDistance > distance) {moved_distance=distance; ready = true;}
//print this to console if we want to debug
if(debug)console.log("v="+v+" interval="+interval+ " call delay = "+count*30 +" moved distance ="+movedDistance)
$timeout( ()=>{
$scope.$apply(()=> {$scope.setWidgetProp( WidgetName, Axis, movedDistance)})
},count*50);
if(ready) break; }
}
//============ end of $scope.translateOnAxis
//definition of the click function
$scope.testModel1Click= function(){
//translate model "model-1"
// 1 meter about along the "y" axis
// speed is 0.1 m/sec - not exact
$scope.translateOnAxis("model-1","y",1,0.1)
}
The function testModel1Click we can use then for model-1 - click event
And then when testing it :
Analogous you can define testModel2Click() for the translation of model-2 and testModel3Click() for the translation of model-3
At the end I want to mention that my opinion, moving modelItem widget is better as movement of model widget but it is up to you how to design it.
Hello Vivekse,
So, I suppose that's you have followed these steps :
$scope.moveOnYAxis = function() {
$scope.setWidgetProp( "model-test", "ty", $scope.getWidgetProp( "model-test", "ty") + 1.0);
}
.
What this function is doing ?
$scope.getWidgetProp( "model-test", "ty") is looking the current position on the Y axis (ty) of the 3D model named model-test
$scope.setWidgetProp( "model-test", "ty", is to modify the position on the Y axis of of the 3D model named model-test
We apply + 1.0 on the current location.
So, 3D Model will move up!
Best regards,
Samuel
Thank you for the reply but it's still not working.
Hi @vivekse
I think JavaScript expression in your project is not quite correct !
$scope.moveOnYAxis = function() {
$scope.setWidgetProp( "model-1", "ty", $scope.getWidgetProp( "model-test", "ty") + 1.0);}
>> the following problems:
1.) translation axis coud be "x", "y" and "z" and rotations respectively "rx", "ry" and "rz" -> property “tx" does not exist
2.) so far I know we have setWidgetProp but we do not have getWidgetProp !
You need to use the syntax $scope.view.wdg[WidgetName][propertyName] instead
Another problem is that this code will have as result a jump. But so far, I understand you need continuous movement. Right?
A correct approach could be this one (add this code 1:1 in your project Home.js) :
/////////////////// function translateOnAxis definition with arguments
//function Arguments:
// WidgetName --> e.g. "model-1"
//Axis --> could 2x", "y" or "z"
//distance --> in meter m=1 is 1meter
//speed --> in meter per second
///////////////// translateOnAxis function body
$scope.translateOnAxis = function(WidgetName,Axis,distance,speed) {
var debug=false; // when true prints in the console but make slow!
var interval = 0.05*speed // distance for 0.05 sec
var count=0;
var ready = false;
//=== loop for the movement
for(v=0;v< distance;v+=interval)
{count++ // this counts the step
let movedDistance=($scope.view.wdg[WidgetName][Axis]+ interval*count)
//check if we arrieved on the final destination
if (movedDistance > distance) {moved_distance=distance; ready = true;}
//print this to console if we want to debug
if(debug)console.log("v="+v+" interval="+interval+ " call delay = "+count*30 +" moved distance ="+movedDistance)
$timeout( ()=>{
$scope.$apply(()=> {$scope.setWidgetProp( WidgetName, Axis, movedDistance)})
},count*50);
if(ready) break; }
}
//============ end of $scope.translateOnAxis
//definition of the click function
$scope.testModel1Click= function(){
//translate model "model-1"
// 1 meter about along the "y" axis
// speed is 0.1 m/sec - not exact
$scope.translateOnAxis("model-1","y",1,0.1)
}
The function testModel1Click we can use then for model-1 - click event
And then when testing it :
Analogous you can define testModel2Click() for the translation of model-2 and testModel3Click() for the translation of model-3
At the end I want to mention that my opinion, moving modelItem widget is better as movement of model widget but it is up to you how to design it.
Thank you for your help🙂
I have just one more question. I tried to move the model in -Y axis edited the code but it didn't work. Can you tell me where did i go wrong?
Hi @vivekse ,
yes there are some errors in the JavaScript implementation of this function.
I modified the code so that it is working now.
-added negative direction. To make it simple- when speed or direction is negative, or both – in this case it will move the model in negative direction. Also, I did pass the arguments to the setTimeout function. It seems that it took in the last version of the code the arguments value at time when the asynchronous call was executed but not the argument value at the time when the function was called / - there is delay - which was not considered so that the distance was not correct. Now I think it works
Following example code with functions testModel1Click(),testModel2Click(),testModel3Click)/ for the click events respectively of "model-1", "model-2" and "model-3":
/////////////////// function translateOnAxis definition with arguments
//function Arguments:
// WidgetName --> e.g. "model-1"
//Axis --> could 2x", "y" or "z"
//distance --> in meter m=1 is 1meter
//speed --> in meter per second
///////////////// translateOnAxis function body
$scope.translateOnAxisR = function(WidgetName,Axis,distance,speed) {
var debug=false; // when true prints in the console but make slow!
var count=0;
var ready = false;
var direction =1;
var startValue =$scope.view.wdg[WidgetName][Axis] //start value of the axis
if(distance < 0 || speed < 0) direction = -1;
distance = Math.abs(distance)
speed= Math.abs(speed)
var interval = 0.05*speed // distance for 0.05 sec
var movedDistance =0;
//=== loop for the movement
for(v=0;v< Math.ceil(distance/interval)+1;v++)
{var delta=0;
movedDistance = movedDistance+ interval
//check if we arrieved on the final destination
if (movedDistance > distance) {delta=distance-movedDistance;movedDistance=distance; ready = true;}
else delta=interval;
//print this to console if we want to debug
if(debug)console.log("v="+v+" interval="+interval+ " call delay = "+v*50 +" moved distance ="+movedDistance)
setTimeout( (v,delta,direction)=>{ if(debug) console.log("v["+v+"] propVal="+ $scope.view.wdg[WidgetName][Axis]+" delta= " + direction*delta);
$scope.$apply(()=> {$scope.setWidgetProp( WidgetName, Axis, ($scope.view.wdg[WidgetName][Axis] + direction*delta))})
},v*50,v,delta,direction);
if(ready) break; }
}
//============ end of $scope.translateOnAxis
//definition of the click function
$scope.testModel1Click= function(){
//translate model "model-1"
// 1 meter about along the "y" axis
// speed is 0.3 m/sec - not exact
$scope.translateOnAxisR("model-1","y",1.6,0.3)
}
$scope.testModel2Click= function(){
//translate model "model-1"
// 1.6 meter about along the "y" axis -negative direction
// speed is 0.01 m/sec - not exact
$scope.translateOnAxisR("model-2","y",-1.6,0.3)
}
$scope.testModel3Click= function(){
//translate model "model-1"
// 1 meter about along the "y" axis in negative direction
// speed is 0.08 m/sec - not exact
$scope.translateOnAxisR("model-3","x",-1.0,0.08)
}
Hi @vivekse ,
could you provide an example project (possibly small one without sensitve data) where I could see what you did try and where I could check what is going wrong and try to fix it. Thanks!
Acutely to move an object you do not need to use javaScript coding. You can move it via binding to a parameter /indirect/ or to binding to a 2d widget e.g. slider /direct/
Here I attached a small project displaying this concept. /there is a second view concept2 is more relevant/
In this project I want model-1 to move +y direction for a certain distance when clicked on it and after 10 seconds model-2 and model-3 should also move in +y direction for a certain distance(lets say their y coordinate increases by 10 units). And thanks for the previous reply.🙂