Adjust the bounding box of an item to fit the item.

Does anyone knows how to make something like this? I tried the script but it doesn't work!

Also, the link overhere is wrong. I download from the developer'spage.

http://www.scriptspot.com/3ds-max/Real-Collapse-Maxscript?time=1172813520

 

Thanks.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
arketip's picture

If you only want the

If you only want the bounding box of the selection then it is easy.

First you create an empty mesh. And you attach each object to this new mesh...

 

(
local obj = mesh vertices:#() faces:#()
local addedObjs = for o in selection where superclassof o == GeometryClass collect o
for o in addedObjs do (
try (attach obj o) catch()
)
)

 

note that the "try/catch" is only here because it doesn't function properly in some cases.

arketip's picture

note that this 2

note that this 2 lines:

 

local addedObjs = for o in selection where superclassof o ==

GeometryClass collect o

 

Are the same line. I didn't find something which respects the format of the code.

alexmbr's picture

Well, I need more than the

Well, I need more than the selection, I need the adjust the bounding box of every scene item, because later I will export the items to a game engine. Look at this picture. The items should be like the number one.

http://www.3dtrue.com/max/downloads/RealCollapse.jpg

tete

But thanks anyway.

arketip's picture

:) Ok, you want the oriented

:)

Ok, you want the oriented bounding box of an object. Exactly the inverse.
This problem requests for more code ;)

The good news is i have already coded that.
Unfortunally I didn't find a mathematically solution for that. The precision is limited but sufficient. You can change the variable angleStep...

Here is the code:

struct OBBstruct
(
minPos=[0.0,0.0,0.0],
maxPos=[0.0,0.0,0.0],
size=[0.0,0.0,0.0],
center=[0.0,0.0,0.0],
angle=[0.0,0.0,0.0],
angleQuat
)

fn getSizeVerts theVertsPos theAngle = (
local minCoord=[theVertsPos[1].x,theVertsPos[1].y,theVertsPos[1].z]
local maxCoord=[theVertsPos[1].x,theVertsPos[1].y,theVertsPos[1].z]
for thisPos in theVertsPos do (
if thisPos.x<minCoord.x do minCoord.x=thisPos.x
if thisPos.x>maxCoord.x do maxCoord.x=thisPos.x
if thisPos.y<minCoord.y do minCoord.y=thisPos.y
if thisPos.y>maxCoord.y do maxCoord.y=thisPos.y
if thisPos.z<minCoord.z do minCoord.z=thisPos.z
if thisPos.z>maxCoord.z do maxCoord.z=thisPos.z
)
local sizeCoord=maxCoord-minCoord
local centerCoord=(minCoord+maxCoord)/2.0
(OBBstruct minPos:minCoord maxPos:maxCoord size:sizeCoord center:centerCoord angle:theAngle)
)

fn findOBB obj angleStep = (
local lim=0.00001
local objNumVerts=obj.numVerts
local theVerts=#{1..objNumVerts}
local polyOpGetVert=polyOp.getVert
local theVertsPos=for v in theVerts collect (polyOpGetVert obj v)
local firstOBB=getSizeVerts theVertsPos [0.0,0.0,0.0]
local centerCoord=firstOBB.center
for v in theVerts do theVertsPos[v]-=centerCoord
local OBBarrayLev1=#()
local OBBvolArrayLev1=#()
local maxAngle=90.0
for angleZ=-maxAngle to maxAngle by angleStep do (
local OBBarrayLev2=#()
local OBBvolArrayLev2=#()
for angleY=-maxAngle to maxAngle by angleStep do (
local OBBarrayLev3=#()
local OBBvolArrayLev3=#()
for angleX=-maxAngle to maxAngle by angleStep do (
local q=inverse(eulerToQuat (eulerAngles angleX angleY angleZ))
local theNewVertsPos=for v in theVerts collect ( theVertsPos[v]*q )
local currentAngle=[angleX,angleY,angleZ]
local currentOBB=getSizeVerts theNewVertsPos currentAngle
append OBBarrayLev3 currentOBB
if currentOBB.size.x<lim do currentOBB.size.x=lim
if currentOBB.size.y<lim do currentOBB.size.y=lim
if currentOBB.size.z<lim do currentOBB.size.z=lim
append OBBvolArrayLev3 (currentOBB.size.x + currentOBB.size.y + currentOBB.size.z)
-- append OBBvolArrayLev3 (currentOBB.size.x * currentOBB.size.y * currentOBB.size.z)
)
local idxLev3=findItem OBBvolArrayLev3 (amin OBBvolArrayLev3)
append OBBarrayLev2 OBBarrayLev3[idxLev3]
append OBBvolArrayLev2 OBBvolArrayLev3[idxLev3]
)
local idxLev2=findItem OBBvolArrayLev2 (amin OBBvolArrayLev2)
append OBBarrayLev1 OBBarrayLev2[idxLev2]
append OBBvolArrayLev1 OBBvolArrayLev2[idxLev2]
)
local idx=findItem OBBvolArrayLev1 (amin OBBvolArrayLev1)
local thisOBB=OBBarrayLev1[idx]
thisOBB.angleQuat=eulerToQuat (eulerAngles thisOBB.angle.x thisOBB.angle.y thisOBB.angle.z)
thisOBB.minPos=(thisOBB.minPos*thisOBB.angleQuat)+ firstOBB.center
thisOBB.maxPos=(thisOBB.maxPos*thisOBB.angleQuat)+ firstOBB.center
thisOBB.center+=firstOBB.center
thisOBB
)

clearListener()
obj=selection[1]
if isValidNode obj do (
local objName=obj.name

local thisOBB=findOBB obj 10.0
format "thisOBB=% \n" thisOBB

point pos:thisOBB.center wireColor:red name:(objName+"_OBB_center")
point pos:thisOBB.minPos wireColor:blue name:(objName+"_OBB_min")
point pos:thisOBB.maxPos wireColor:blue name:(objName+"_OBB_max")

local b=box length:thisOBB.size.y width:thisOBB.size.x height:thisOBB.size.z wireColor:green name:(objName+"_OBB")
b.pivot=[0,0,(thisOBB.size.z/2.0)]
b.rotation.controller.x_rotation=thisOBB.angle.x
b.rotation.controller.y_rotation=thisOBB.angle.y
b.rotation.controller.z_rotation=thisOBB.angle.z
b.pos=thisOBB.center
b.xray=true
select b

max views redraw
)

 

 

This code works for 1 object but you can easily adapt it to work for all objects in your scene. Also, the current code is more an demo than a script ready to use. It creates some objects to visualize the results. Off course you can remove it.

 
ps. this code is for the polys objects. Sorry you will have to adapt it a little bit for meshes...

dussla's picture

thank you for good code

thank you for good code
i test this code
If the bounding box that was created is from the original object
It will be generated slightly misaligned
What is the reason?

alexmbr's picture

Thanks

Thanks

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.