Community Tip - Learn all about the Community Ranking System, a fun gamification element of the PTC Community. X
Solved! Go to Solution.
Hello @aks1,
when you try to animate an object with javascript there are some points you need to consider:
1.)Objects which have to be moved /access of the objects
1.1) setting of the property via Javascript: as mention by . This is working fine when you want to move a model, or you have already defined modelitems:
//set rotation about X to 55 degree $scope.setWidgetProp( "modelItem-1", "rx", 55.0);
1.2) when you want to access to object which are not explicitly defined you can use some techniques as described in the post How to select model components in a 3d model without explicit definition of model Items?
In this post is described how to select components which are not explicitly defined as modelitems where then we tried to change mainly the color. But so far I could remember the tml3Renderer object has also methods for translation (setTranslation()name,xy,z)and rotations (setRotation (name, rx, ry, rz)) . E.g.
tml3dRenderer.setTranslation(target + "-" + pathid,1,1,1); //works fine to translate x,y,z 1,1,1,
but anyways the more recommend way is 1.1)
2.) How to calculate the new position.
2.1) speed: means you will change a position relatively by deltaValue e.g.
x = x+ deltaX
or ry= ry+deltaRY
2.2) calculate the absolute position of the coordinate
$scope.setWidgetProp( "modelItem-1", "x", 12.0);
3.) What is the reference Coordinate system. Every model and modelItem has his own coordinate system and all rotation are in regarding to this CSYS and the translation regarding to the parent csys. This is mainly depending on where the model is coming from. For models coming form Creo Parametric you can check the post Mechanism Concept in Vuforia Studio- How to make rotation more easy
4.) the last point is the question which event should change the position
4.1.) changing the position by ui action / clicking of button , voice command .... etc.
4.2)changing the position by starting of an interval callback . please check this post for more information
Placeing animations on modelItems with javascript
4.3) using some watch angular construct to follow a measurement value:
The code above is checking if the value of the app parameter door_angle. The door_angle parameter is bind to a TWX measurement and will change every 1 second where it follows the value of the thingworx measurement. When the parameter door_angle will start a callback function. The function will change to position and the angle of the door where it uses the door_angle parameter to calculate the door rotation. Here the door rotation is not the same as the door_angle because we have different coordinate systems and the door_angle should be transformed to a translation and rotation. Sample code:
/////////////////// ANGLE CONTROL $scope.$watch( function() { //console.log("$scope.$watch() first function door_angle="+$scope.app.params['door_angle']); return $scope.app.params['door_angle']; } , function() { var l_door=0.999; if($scope.view.wdg['toggle-3']['value']==true) { var angle1=$scope.app.params['door_angle']; $scope.view.wdg['slider-1']['value']=angle1; var angle1_rad=angle1*Math.PI/180.0; $scope.view.wdg['modelItem-door-asm']['rx'] = angle1 ; $scope.view.wdg['modelItem-door-asm']['y'] = 0.0 - l_door*Math.sin(angle1_rad); $scope.view.wdg['modelItem-door-asm']['z'] = 0.0 - l_door*(1.0-Math.cos(angle1_rad)); } //endif } //end of the second function ); // end of the watch function /////////////////////////////////////////////////////////////////////////////
4.4) the last concept for movement events is to use a loop. In this case we have an array with values and we have a loop where we can set the property to the current value of the loop/array. Afterwords we will call some delay function and go to the next loop step. Some thing like this (never tested it 😞
let a = [1, 2, 3 .... 1001,1002]; for (let index = 0; index < a.length; ++index) { let value = a[index]; setTimeout( function () { $scope.setWidgetProp( "modelItem-1", "x", a[index]); },1000*index); }
// the loop will be executed immediately, means //asynchronous issue... loop will not need much time // before every next call will be delayed by 1sec*index
Hello,
I have found this tutorial in the help center of Vuforia Studio in PTC web site :
http://support.ptc.com/help/vuforia/studio/en/#page/Studio_Help_Center%2FBeginner_Bindings.html%23
It explains how to rotate a 3D Model with binding.
To translate a 3D Model, it is similar but it just need to bind to X, Y or Z Coordinate property.
If for your Project, it is needed to use Javascript, the solution is to use $scope.setWidgetProp javascript function.
For example, for a Model named model-test :
// To translate on x axis $scope.setWidgetProp( "model-test", "x", 10.0); // To rotate on y axis $scope.setWidgetProp( "model-test", "ry", 10.0);
Best regards,
Samuel
I'd suggest looking at the Quadcopter sample project that comes with Studio. All the movement of the model is done via JS, except for the battery removal which is a Creo Illustrate sequence.
Hello @aks1,
when you try to animate an object with javascript there are some points you need to consider:
1.)Objects which have to be moved /access of the objects
1.1) setting of the property via Javascript: as mention by . This is working fine when you want to move a model, or you have already defined modelitems:
//set rotation about X to 55 degree $scope.setWidgetProp( "modelItem-1", "rx", 55.0);
1.2) when you want to access to object which are not explicitly defined you can use some techniques as described in the post How to select model components in a 3d model without explicit definition of model Items?
In this post is described how to select components which are not explicitly defined as modelitems where then we tried to change mainly the color. But so far I could remember the tml3Renderer object has also methods for translation (setTranslation()name,xy,z)and rotations (setRotation (name, rx, ry, rz)) . E.g.
tml3dRenderer.setTranslation(target + "-" + pathid,1,1,1); //works fine to translate x,y,z 1,1,1,
but anyways the more recommend way is 1.1)
2.) How to calculate the new position.
2.1) speed: means you will change a position relatively by deltaValue e.g.
x = x+ deltaX
or ry= ry+deltaRY
2.2) calculate the absolute position of the coordinate
$scope.setWidgetProp( "modelItem-1", "x", 12.0);
3.) What is the reference Coordinate system. Every model and modelItem has his own coordinate system and all rotation are in regarding to this CSYS and the translation regarding to the parent csys. This is mainly depending on where the model is coming from. For models coming form Creo Parametric you can check the post Mechanism Concept in Vuforia Studio- How to make rotation more easy
4.) the last point is the question which event should change the position
4.1.) changing the position by ui action / clicking of button , voice command .... etc.
4.2)changing the position by starting of an interval callback . please check this post for more information
Placeing animations on modelItems with javascript
4.3) using some watch angular construct to follow a measurement value:
The code above is checking if the value of the app parameter door_angle. The door_angle parameter is bind to a TWX measurement and will change every 1 second where it follows the value of the thingworx measurement. When the parameter door_angle will start a callback function. The function will change to position and the angle of the door where it uses the door_angle parameter to calculate the door rotation. Here the door rotation is not the same as the door_angle because we have different coordinate systems and the door_angle should be transformed to a translation and rotation. Sample code:
/////////////////// ANGLE CONTROL $scope.$watch( function() { //console.log("$scope.$watch() first function door_angle="+$scope.app.params['door_angle']); return $scope.app.params['door_angle']; } , function() { var l_door=0.999; if($scope.view.wdg['toggle-3']['value']==true) { var angle1=$scope.app.params['door_angle']; $scope.view.wdg['slider-1']['value']=angle1; var angle1_rad=angle1*Math.PI/180.0; $scope.view.wdg['modelItem-door-asm']['rx'] = angle1 ; $scope.view.wdg['modelItem-door-asm']['y'] = 0.0 - l_door*Math.sin(angle1_rad); $scope.view.wdg['modelItem-door-asm']['z'] = 0.0 - l_door*(1.0-Math.cos(angle1_rad)); } //endif } //end of the second function ); // end of the watch function /////////////////////////////////////////////////////////////////////////////
4.4) the last concept for movement events is to use a loop. In this case we have an array with values and we have a loop where we can set the property to the current value of the loop/array. Afterwords we will call some delay function and go to the next loop step. Some thing like this (never tested it 😞
let a = [1, 2, 3 .... 1001,1002]; for (let index = 0; index < a.length; ++index) { let value = a[index]; setTimeout( function () { $scope.setWidgetProp( "modelItem-1", "x", a[index]); },1000*index); }
// the loop will be executed immediately, means //asynchronous issue... loop will not need much time // before every next call will be delayed by 1sec*index