Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How can I manipulate the Size of a BasePart to eliminate unnecessary CFrame components?

What I'm trying to do:

I want to encode the CFrame of a part, but hopefully eliminate the rotation matrix if it is unnecessary (all bricks will end up facing upwards, and that is fine). For example, if the Rotation = Vector3.new(90, 0, 0) then we can remove the need to encode rotation by switching the z and y coordinates of Size: Size = Vector3.new(Size.x, Size.z, Size.y)

I don't want to modify the rotation or Size of the part I am encoding, so I want to manipulate the data only.

Here is unconfirmed ways you are supposed to manipulate the xyz's:

Rot		=	Vector3.new(0, 0, 0)
Size	=	Vector3.new(x, y, z)

Rot		=	Vector3.new(0, 0, 90)
Size	=	Vector3.new(y, x, z)

Rot		=	Vector3.new(0, 90, 0)
Size	=	Vector3.new(z, x, y)

Rot		=	Vector3.new(90, 0, 0)
Size	=	Vector3.new(x, z, y)

Rot		=	Vector3.new(90, 90, 0)
Size	=	Vector3.new(y, z, x)

Rot		=	Vector3.new(90, 0, 90)
Size	=	Vector3.new(z, x, y)

Also keep in mind there are positive and negative 90's and 180's, those are the same to us, so let's narrow the possibilities:

-- Make stuff positive
-- 180's can be removed, as they do not change anything except which way the brick is facing
-- This modifies Rotation, but the final script hopefully will not
if brick.Rotation.x = -90 then brick.Rotation = Vector3.new(90, brick.Rotation.y, brick.Rotation.z) end
if brick.Rotation.y = -90 then brick.Rotation = Vector3.new(brick.Rotation.x, 90, brick.Rotation.z) end
if brick.Rotation.z = -90 then brick.Rotation = Vector3.new(brick.Rotation.x, brick.Rotation.y, 90) end
if brick.Rotation.x == 180 or brick.Rotation.x == -180 then brick.Rotation = Vector3.new(0, brick.Rotation.y, brick.Rotation.z) end
if brick.Rotation.y == 180 or brick.Rotation.y == -180 then brick.Rotation = Vector3.new(brick.Rotation.x, 0, brick.Rotation.z) end
if brick.Rotation.z == 180 or brick.Rotation.z == -180 then brick.Rotation = Vector3.new(brick.Rotation.x, brick.Rotation.y, 0) end

This is how you isolate the Rotation Matrix in a CFrame:

local rotation = part1.CFrame - part1.Position
local x, y, z, R00, R01, R02, R10, R11, R12, R20, R21, R22 = rotation:components()

I don't expect anyone to write this script for me. What I would like to know from someone, is if it is possible to write this script without manually checking for each specific case, and then acting accordingly. Again, the script can't modify the Brick we are finding the CFrame of. Any ideas?

2 comments

1

I suppose the question here is why do you want to do this? If you're saving this data per-part in a Table, you're not losing out on pretty much any data.

0

I want to eliminate the Rotation Matrix

1 answer

✓ Accepted answer

Here is a solution assuming the part of axis-aligned (but maybe rotated by 90 degrees in any way)

(note that for non-symmetrical textures like wood and sand, it might not be correct to eliminate the rotation as you want)

local low = part.CFrame * (part.Size / 2)
loacl high = part.CFrame * (-part.Size / 2)

local dx = math.abs(high.x - low.x)
local dy = math.abs(high.y - low.y)
local dz = math.abs(high.z - low.z)

Then a part with CFrame CFrame.new(part.Position) and size Vector3.new(dx, dy, dz) should take up the same space that part does.

I think you can check that the part is axis aligned by just making sure the dimensions are the same, just reordered:

local old = {part.Size.x, part.Size.y, part.Size.z}
local new = {dx, dy, dz}
table.sort(old)
table.sort(new)
if old[1] == new[1] and old[2] == new[2] and old[3] == new[3] then
	-- was (probably) axis aligned!
else
	-- was definitely not axis aligned
end

2 comments

0

How does this work?

0

You measure between two opposite corners. The (absolute value of the) differences in X, Y, Z are going to be the X, Y, and Z respectively of the size of the part you want.

This discussion is preserved as it was. New answers, comments, and votes are closed.