Model resize code "forgets" part orientation

Been using @Crazyman32’s model resize code and it works well (good job). However, I have run into a frustrating issue it creates, and I can’t figure out how to fix it. This code seems to completely reset the orientation of my parts (or something like that?)

local function ScaleModel(model, scale)
	local primary = model.PrimaryPart
	local primaryCf = primary.CFrame
	for _,v in pairs(model:GetDescendants()) do
		if (v:IsA("BasePart")) then
			v.Size = (v.Size * scale)
			if (v ~= primary) then
				v.CFrame = (primaryCf + (primaryCf:inverse() * v.Position * scale))
			end
		elseif v:IsA("SpecialMesh") then
			v.Scale = v.Scale * scale
		end
	end
	return model
end 


I’m really lost as to what’s causing this issue. Can anyone help?

What is the primary part you are referring to? It seems like you are the one resetting the CFrame -

You’re using the iterated part’s position, but that just adds onto the base part’s position. There’s no mention of the original CFrame for the iterated part, instead you are wiping all the iterated parts with the Primary, plus the inverse of it times some multiplier. They will then have the same orientation.

That’s what I garnered, not sure if it’s something else or if I’m completely wrong lol. Hope this helps.

1 Like

Ahh, thank you for pointing that out. I will try messing with that line and see if I can get this to work

1 Like

This is my high-tech solution:

local orientation = v.Orientation
v.CFrame =(primaryCf + (primaryCf:inverse() * v.Position * scale))
v.Orientation = orientation

It works better, but I know this is not the right way to do this. I need someone smarter than me to correct me here

I’m actually in a rush right now, so I’m not really thinking but this is what I would try:

v.CFrame =(primaryCf + (primaryCf:inverse() * v.Position * scale))*v.CFrame

I’m pretty sure that does the same as what you did in your “high-tech” way but then again CFrames always trick me. I will probably be unable to respond to this thread for the next few hours so if it doesn’t work, hopefully someone else smarter than me pops up and figures out what’s going on.

EDIT:

Note that I’m horrible with CFrames but ignore what I did up there.

v.CFrame = CFrame.new(v.Position * scale, v.Orientation)
That is my way of doing a resize. But using your method,

v.CFrame = (primaryCf + (primaryCf:inverse()*v.Position*scale))*CFrame.new(v.Orientation)

But again I’m no genius, at this point I’m hoping someone comes along and figures out that my CFrame math is garbage. I’ll try to explain what I’m doing, though.

The first method (after blurred) is just creating a new CFrame out of the original position (times a scaling factor) and the original orientation. I haven’t tested it but it seemed a lot simpler than what you have written.

The second method is tacking on the original CFrame, using your code. I think there’s a lot of messy ways to do CFrame math, and every time I see “inverse” I am pretty sure there should be an easier way to do things.

Okay for real now I am unavailable lol, good luck!

1 Like

i’m not sure if you found a solution to your problem yet…, (there are couple of ways to fix it) but one way to fix your problem is by constructing a new CFrame for primaryCf, so the rotation is removed…

local primaryCf =  CFrame.new(primary.Position)

Then apply rotation back, this time the part’s rotation…

local Rotation =  (v.CFrame - v.Position) 
v.CFrame = (primaryCf + (primaryCf:inverse()*v.Position*scale)) * Rotation

Then Everything works perfectly

5 Likes

Thanks for this folks… This was driving me crazy for a number of hours tonight.
Here’s my finalized function for anyone else pulling their hair out over this. :slight_smile:

local function scaleModel(model, scale)

	local primary = model.PrimaryPart
	local primaryCf = CFrame.new(primary.Position)			
	
	for _,v in pairs(model:GetDescendants()) do
		if (v:IsA("BasePart") or v:IsA("UnionOperation")) then
			v.Size = (v.Size * scale)
			if (v ~= primary) then
				local Rotation = (v.CFrame - v.Position)
				v.CFrame = (primaryCf + (primaryCf:inverse()*v.Position*scale)) * Rotation				
			end
		end
	end

	return model

end

modelA = scaleModel(model, .85)  -- returns 85% of original size
modelB = scaleModel(model, 2.5)  -- returns 250% of original size

2 Likes