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
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.
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.
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
But thanks anyway.
:) 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...
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?
Thanks
Thanks