Notifications
Clear all

[Closed] Check if pivot is inside object

How can I check if pivot is inside object? I’m pretty new at maxscript and so far I only know how to do some rollout stuff

8 Replies

Actually not inside object but inside object bounding box.

It’s easy : you just have to check if the pivot coordinate is “inside” the bounding box coordinates.

The bounding box is defined by two points, which are located on the opposites, i.e the segment that links these two points is one diagonal line of the bounding box.


   [b]fn[/b] isPivotInBBox theNode =
   (
   	bbox =  nodeLocalBoundingBox theNode
   	thePivot = theNode.pivot
   	
   	[b]if 	[/b](bbox[1].x<=thePivot.x and thePivot.x<=bbox[2].x) AND \
   		 (bbox[1].y<=thePivot.y and thePivot.y<=bbox[2].y) AND \
   		 (bbox[1].z<=thePivot.z and thePivot.z<=bbox[2].z)
   	[b]then [/b]return true
   	 [b]else [/b]return false
   )

Then if you want to test this function on “Teapot01” just write :

isPivotInBBox $Teapot01

it returns true or false.

almost @groutcho, to use that method, the pivot and localboundingbox needs to be aligned; max returns world coordenates:

	(
	   fn isPivotInBBox theNode =
	   (
	   
		M= inverse (rotate (matrix3 1) (theNode.transform))
		A=#()
		for i in nodeLocalBoundingBox theNode do append A i
		append A theNode.pivot
		for j in 1 to A.count do A[j]*=M
	   
			if 	(A[1].x<=A[3].x and A[3].x<=A[2].x) AND \
			 (A[1].y<=A[3].y and A[3].y<=A[2].y) AND \
			 (A[1].z<=A[3].z and A[3].z<=A[2].z)
		then return true
		 else return false
		)
		isPivotInBBox $
	)

Thanks guys, Ruramuq’s method works great! I had no idea you needed to align pivot and bounding box. I better start reading maxscript reference more because all these matrices and math and stuff makes my head spin

here is probably the most safe for brain method:


fn isPivotInsideBBox node = 
(
	node.pivot.x >= node.min.x and node.pivot.x <= node.max.x \
	and
	node.pivot.y >= node.min.y and node.pivot.y <= node.max.y \
	and
	node.pivot.z >= node.min.z and node.pivot.z <= node.max.z
)

If its already aligned to world(no rotation), yes, no need to complicate this.
But otherwise if its rotated, it won’t be accurate.

(and in case the pivot itself is transformed(rotated), then the BBox would need to be aligned to the objectTransform)

  if you test your code more accurate you will see that it doesn't work right in case of scale transformation.
  
  if you think that I don't see the difference between [b]local[/b] and[b] world [/b]bbox here is it:

      struct bounds (bmin, bmax)
     fn isPointInsideBBox pos bbox = 
     (
     	pos.x >= bbox.bmin.x and pos.x <= bbox.bmax.x \
     	and
     	pos.y >= bbox.bmin.y and pos.y <= bbox.bmax.y \
     	and
     	pos.z >= bbox.bmin.z and pos.z <= bbox.bmax.z
     )
     fn isPivotInsideBBox node bbType:#world = 
     (
     	tm = case of
     	(
    		(bbType == #local): node.objectTransform
		(iskindof bbType Matrix3): bbType
    		default: matrix3 1
     	)
     	bbox = nodeGetBoundingBox node tm
     	bbox = bounds bmin:bbox[1] bmax:bbox[2]
     		
     	isPointInsideBBox (node.pivot*(inverse tm)) bbox
     )
     isPivotInsideBBox $ bbType:#local

aha, your right, the code I posted does not work with scale, I didnt thought about it, probably because its a bad practice to have scaled objects in scene, except objectoffsetscale

I know you know, but some readers may not see the importance of it… in any case, the code you’ve posted is a much better example to learn.