Scale a transform's localScale alongside intended world axis?

*Update: This question has been superceded as the interface approach taken has been fully revised – a video and new code here: Vector3 question: How to know right axis when using pinch punch gestures to scale object in virtual reality? - Questions & Answers - Unity Discussions *

I would like the user (using a Vive) to adjust a given held transform’s localScale by using the other hand’s relative motion during a trigger press. For instance, if the left hand as below makes the direction meaning up/ grow (where up, right and forward = increase, and reverse for shrinking), then I would like the localScale of the right pictured cuboid to grow alongside [a], as that’s currently closest to the intended up. However, since the cuboid transform is already rotated, how do I find out at which of x/y/z of the localScale should scale as per intended direction?

69085-exampleimage.png

Here’s a non-working example code try:

    Vector3 rotatedPoint = RotatePointAroundPivot(currentHandTransform.position, positionEmptyClickStarted, -otherHandTransform.eulerAngles);
    Vector3 differenceVector = rotatedPoint - positionEmptyClickStarted;
    otherHandTransform.localScale = otherHandTransformStartScale + differenceVector;

// snip

Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 angles) {
    Vector3 dir = point - pivot;
    dir = Quaternion.Euler(angles) * dir;
    point = dir + pivot;
    return point;
}

Thanks for any help!

When you say ‘find the closest’ I’m going to assume you mean in screen space, as this seems most natural, if x is a 2D vector,

  1. So first, turn you objects directional vectors into screen space directions.
  2. Compare this to the ‘drawn’ users vector, either by angle, or projected value etc
  3. Choose the direction with least angle difference of highest influence
  4. Use the influence to scale the object in that direction

Untested code:
Vector2 xVector; //in pixels
Transform trans;
Camera camera;

void Scale(x, trans){
	Vector2[] vecs = new Vector2[3];
	Vector2 pos = (Vector2)camera.WorldToScreenPoint(trans.position);

	vecs[0] = (Vector2)camera.WorldToScreenPoint(trans.position + trans.right)-pos;
	vecs[1] = (Vector2)camera.WorldToScreenPoint(trans.position + trans.up)-pos;
	vecs[2] = (Vector2)camera.WorldToScreenPoint(trans.position + trans.forward)-pos;

	float influence = Mathf.NegativeInfinity;

	int ss = -1;
	int ii = 0;

	for(int s = -1; s < 2; s+=2){
		for(int i = 0; i < 3; i++){
			
			float inf = Influence2D(x, s*vecs*);*
  •  	if(inf > influence){*
    
  •  		influence = inf;*
    
  •  		ss = s;*
    
  •  		ii = i;*
    
  •  	}*
    
  •  }*
    
  • }*

  • Vector3 scale = trans.localScale;*

  • switch(ii){*

  •  case 0:*
    

_ scale.x += ss*ii;_

  •  	break;*
    
  •  case 1:*
    

_ scale.y += ss*ii;_

  •  	break;*
    
  •  case 2:*
    

_ scale.z += ss*ii;_

  •  	break;*
    
  • }*

  • trans.localScale = scale;*
    }

float Influence2D(Vector2 vector, Vector2 norm){

  • return Vector2.Dot(vector, norm)/(norm.magnitude);*
    }