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

Changing the spatial/gesture scale via JavaScript

AllanThompson
16-Pearl

Changing the spatial/gesture scale via JavaScript

Hi All,

 

Does anyone know if there's a way to change what I'm calling the the spatial scale - the overall scale of the experience that you change via the pinch gesture, via JavaScript?

 

I've got a HoloLens experience using a ThingMark that uses a large model (approx 20m long, 6m wide, 3m high).  When I initially load the model, I have it shown at about 10% of true size, so the whole thing fits into the field of view of the HoloLens.  I have then build voice commands with some associated JavaScript to change the scale of the model.  This is all working fine, but it becomes a problem if I want to add additional elements such as a gauge or 3D Image.  For these to be placed correctly, I need to specify their x,y,z coordinates and as they must be specified in absolute values, I need to then hard-code them based on the size of the model to make sure they are in the correct location relative to the model at that particular scale.

 

I've played around with scaling the ThingMark size as mentioned by @JGridlock in his post here, and it's working, but my feeling is that this is a hack that could stop working with an update.

 

Ideally, I could use a spatial tracking experience and then as I drag to resize, it moves and scales everything in the experience, but:

  1. It's pretty much impossible to drag the handles on the bounding box that appears around a model that is this big.
  2. Spatial works best when you start at original and then drag to make it bigger or smaller.  I want to start small, and be able to make it bigger, but to an exact scale - 1:1.

So my thinking is that I place the experience with a "spatial scale" of 10% and then I use JavaScript via voice commands to change the spatial scale to the values that I want, and everything in the experience will just scale along.

 

Any ideas?

 

Many thanks,

 

Allan

7 REPLIES 7

Hi Allan, 

 

I thought of using model items and binding the gauges to the items. 

I used the following code:

$scope.makeBig = function() {
$scope.view.wdg['model-1']['scale'] = 1.0000;
$scope.view.wdg['3DGauge-1']['x'] =$scope.view.wdg['modelItem-1']['x'];
$scope.view.wdg['3DGauge-1']['y'] =$scope.view.wdg['modelItem-1']['y'];
$scope.view.wdg['3DGauge-1']['z'] =$scope.view.wdg['modelItem-1']['z'];

}

Unfortunately this won't work properly. Their value changes to the right number, but in the preview, the position isn't right. But maybe the idea can help you.

 

Greetings

whity

Thanks @whity.

 

That's how I've done it at the moment.  The problem is that I need to have an application parameter for the X and Y position of every gauge that I add.  So my code looks like this:

 

$scope.app.small = function() {
$scope.app.params.modelscale = 0.25;
$scope.app.params.GaugeScale = 1;
$scope.app.params.RPMx = -0.919;
$scope.app.params.RPMy = 0.255;
$scope.app.params.Tempx = -0.774;
$scope.app.params.Tempy = 0.53;
$scope.app.params.Oilx = -0.469;
$scope.app.params.Oily = 0.591;
$scope.app.params.Fuelx = 0.856;
$scope.app.params.Fuely = 0.171;
}

 

$scope.app.big = function() {
$scope.app.params.modelscale = 1;
$scope.app.params.GaugeScale = 2;
$scope.app.params.RPMx = -3.421;
$scope.app.params.RPMy = 1.231;
$scope.app.params.Tempx = -2.643;
$scope.app.params.Tempy = 2.038;
$scope.app.params.Oilx = -1.866;
$scope.app.params.Oily = 2.189;
$scope.app.params.Fuelx = 3.167;
$scope.app.params.Fuely = 1.044;
}

 

It's not too bad, but I"m looking to build a lot more 3D elements into the experience (images and labels) and these will most likely need to have x, y and z controlled for each size.  It's simple to do, but you end up with a lot of having to work out where everything goes and hardcoding everything in.

 

Spatial is great because I can just scale the whole thing and all the positions update - much less coding, which I"m always a fan of.

 

Cheers,

 

Allan

I have a similar problem to what you have described.

I'm using spatial target to place an object on the floor. After that the user can modify the object with the built-in gesture control, but I would like to limit the scale so that the user wouldn't be able to scale above 100% and not below 10%.

 

I haven't found a way of detecting when the scale gesture happens (in javascript). The object itself seems to have the same scale even though it's scaled with gestures. Is it the tracking target itself that gets scaled?

Has anyone been able to read what the current scale factor is after a scale gesture?

 

Thanks,

Tony

I'm not sure that changing the scale of the ThingMark is a hack. I think it is just the other side of the frame of reference from what you are doing with the model scale. Unless PTC is saying otherwise I would do it.

 

If you move on with scaling all the items you could simplify it a lot by not using application parameters for everything and just doing it all in a JS function called on "Value Changed" for the slider. Here is a function i wrote to update 36 different x, y, z, rx, ry, rz values on slider movement to allow you to move a mechanism with a slider.

 

$scope.kinematicUpdate = function () {
    let position = $scope.view.wdg['slider-kin'].value;
    let studioIDArray = Object.keys(kinematicsJSON[position]); //array of studioIDs to update
    for(let i = 0; i < studioIDArray.length; i++) { //get into the "time" object
        let theStudioID = studioIDArray[i]; //studioID for object to update
        let propertyArray = Object.keys(kinematicsJSON[position][theStudioID]); //make an array of the keys, "x, y, rx" etc...
            for(let y = 0; y < propertyArray.length; y++) {
            let theProperty = propertyArray[y];
            let theValue = kinematicsJSON[position][theStudioID][theProperty];
            // console.log("ID, Prop, value ", theStudioID, theProperty, theValue);
            $scope.setWidgetProp(theStudioID, theProperty, theValue);
        };
    };
};

and here is a sample of the JSON object it is reading from.

{
    "0": {
       "modelItem-kin-cs": {
          "rx": 0,
          "ry": 0,
          "rz": -0.002016251,
          "x": -0.00000191786,
          "y": 1.75985e-7,
          "z": 0
       },
       "modelItem-kin-link": {
          "rx": 0,
          "ry": 0,
          "rz": -0.005322145,
          "x": -0.0000179498,
          "y": 0.00000190598,
          "z": 0
       },
...
 "1": {
       "modelItem-kin-cs": {
          "rx": 0,
          "ry": 0,
          "rz": -2.08465873,
          "x": -0.00197919,
          "y": 0.00021795,
          "z": 0
       },
       "modelItem-kin-link": {
          "rx": 0,
          "ry": 0,
          "rz": -5.391225358,
          "x": -0.018065299,
          "y": 0.002781849,
          "z": 0
       },
...
    "2": {
       "modelItem-kin-cs": {
          "rx": 0,
          "ry": 0,
          "rz": -4.099274077,
          "x": -0.00388313,
          "y": 0.000496852,
          "z": 0
       },
       "modelItem-kin-link": {
          "rx": 0,
          "ry": 0,
          "rz": -10.42893833,
          "x": -0.034640691,
          "y": 0.006904911,
          "z": 0
       },
...

You could build an object with the initial position of all your objects and then multiply them by the scale value and update instead of looking up by position like i did.

I also do not think that scaling of  the thingmark will be a hack. So mostliy the users will try to have the same size for a printed thingmark and the thingmark in the project. But I do not think that the scan process will make a difference of the real size. I think it  simple scan the size of the thingmark in the real world then then compare it to the size of the thingmark from project and will calculate a global scale factor for all objects (not only 3d models but also 3d label and images). In the most cases the both sizes are the same and the factor is then 1. But I do not believe that this functionality   should be deactivated in the future, because there is no standard size of thingmark and customer could use thingmarks with different size.  This is the best way to scale all objects without having information of the different objects.

The other approach to scale the model (scale factor) - will scale only the 3d objects. So means all other object will not change. So if we want scale als they location we need also an solution as mention by @jmikesell where we have some loops by scaling of the coordinates of all objects with same factor which we use to scale the model ( the requirments is that model cordinate is not moved  or rotated) if we have  a model which have  coordinates which are not x,y,z,rx,ry,zy= (0,0,0,0,0,0) - in this case we need to  consider this for the recalculating of the of the location of the other 3d elements.

The  x,y,z values of the 3d model location should be simple added to the location of the other 3d entities.. Having alsa rotations will make it more complex and so we need to calculate a transformation matrix where we can multiply the (x, y,z) vector of the current location to find the scaled location. For more background  info ,please see 3D geometric transformation

 

@AllanThompson

 

Hope you are doing good. Could you please confirm if the issue has been resolved.

 

If yes, please mark the answer as accept as solution for the future reference. Thank you in advance.

Regards-Mohit Goel

Hi All,

 

Some updates on this post since @mgoel appears to be going through every post in the forum asking people to mark them as solved.

 

My requirements for the experience have evolved a bit since my original post.  The original experience could have worked fine by scaling everything in the experience and the hack of scaling the ThingMark works great for this.  But now I have some elements that I want to scale (the model and associated gauges, labels and images) and some that I don't (some images that I have placed on the floor and made behave like toggle buttons using JS).

 

So really now that the experience requirements have changed, the "spatial scale" option that I originally asked about wouldn't really help at all and neither will the ThingMark size hack.

 

@jmikesell's method of scaling looks like a way to help me reduce the amount of code and I'll look at using that as I move forward and develop things more.

 

But as for my original question about using JS to control what I called the "spatial scale" or the gesture scale, I still haven't seen any answer as to whether that's possible or not.

Announcements

Top Tags