Is there a way to get every single orientation value inside of a table index?

I am trying to create an orientation converting module which converts orientation values to numbervalues which could save a bit of characters and then load the orientation values via the loaded numbervalues.

What is the best way to achieve this?

table2[1] = vector3.new(180,0,0) -- table for loading orientation from number

table4[vector3.new(180,0,0)] = 1 -- table for loading number from orientation
table4[vector3.new(-180,0,0)] = 1 -- table for loading number from orientation

table4[vector3.new(0,180,0)] = 2
table4[vector3.new(0,-180,0)] = 2
1 Like

This is vague. Can you explain what you are trying to do in more detail?

I am trying to make a module where i can convert an orientation value to a number value so that i could save the number instead of the orientation value to save a few characters.

There is a way to reduce the rotation normal vectors into two angles which might help. I don’t know any way to compress it down to 1 number (it’s probably impossible)

I want to call a number from an orientation value like this

table2[1] = vector3.new(180,0,0) -- table for loading orientation from number

table4[vector3.new(180,0,0)] = 1 -- table for loading number from orientation
table4[vector3.new(-180,0,0)] = 1 -- table for loading number from orientation

table4[vector3.new(0,90,0)] = 2 -- 90 is the same orientation as -90 so the part is looking at the same direction.
table4[vector3.new(0,-90,0)] = 2

it doesn’t have to be vector3, it could be a string aswell.

If you want to keep the Vector3’s as keys for the table, you could probably write a comparison function:

function compareVector3(v1, v2)
	-- may want to round due to floating points?
	return v1.X == v2.X and v1.Y == v2.Y and v1.Z == v2.Z
end

-- get number from orientation
function getNumberFromOrientation(orientation)
	for storedOrientation, number in pairs(table4) do
		if compareVector3(orientation, storedOrientation) then
			return number
		end
	end
end

-- other way around
function getOrientationFromNumber(number)
	for orientation, storedNumber in pairs(table4) do
		if number == storedNumber then
			return orientation
		end
	end
end

I dont need the comparing function, thats all set and easy to do, but i need to store the orientation values inside of a table.

Storing every possible orientation vector as a unique number is a bad idea. You could do it, but it isn’t worth it (unless there are only a few orientation vectors you are using, like up, down, left , right, etc.)

The orientation is every single combination with a difference of 90. so like

vector3.new(180,0,0)
vector3.new(90,0,0)
vector3.new(0,0,0)
vector3.new(-90,0,0)
``` etc

I don’t quite understand what you mean here, and it doesn’t seem like it’s as simple as I think. Could you explain a bit more?

i need to create every orientation combination from -180 to 180 for X,Y and Z and insert it into a table.

The best way to do this is to store 2 angles from rotation normals, like I said above. It is better than storing 3 positional numbers

It sounds like you could use some form of enum. Consider the following:

-- Helper function that, when given two Vector3 values, returns if both Vector3 values are equal.
local function vector3IsEqual(vectorOne, vectorTwo)
	return vectorOne.X == vectorTwo.X
		and vectorOne.Y == vectorTwo.Y
		and vectorOne.Z == vectorTwo.Z;
end

-- Enum-like object, thus we should use PascalCase
local Orientation = (function()
	local Orientation = {};
	-- Populate our integer indexes with the Vector3 values in the range [-180, 180] in steps of 90.
	for x = -180, 180, 90 do
		for y = -180, 180, 90 do
			for z = -180, 180, 90 do
				local vector = Vector3.new(x, y, z);
				Orientation[#Orientation + 1] = vector;
			end
		end
	end
	
	-- Allow the dynamic lookup of Vector3 values. Essentially, allow for reverse mapping.
	local function lookupVector3(self, indexVector)
		if (typeof(indexVector) ~= "Vector3") then return nil; end
		for intIndex, mappedVector in ipairs(self) do
			if vector3IsEqual(indexVector, mappedVector) then
				return intIndex;
			end
		end
	end
	
	setmetatable(Orientation, { __index = lookupVector3 });
	return Orientation;
end)();

print(Orientation[Vector3.new(0, 0, 0)]);
-- Prints "63" (tested in Studio!)

print(Orientation[63]);
-- Prints "0, 0, 0" (tested in Studio!)

This seems to be what you desire, a table that can “serialize” orientation values to a single integer which could later be “deserialized” to acquire an orientation value.

Sorry… I am terrible at explaining things…
I already have the converting function

for x = -180, 180, 90 do -- create xyz in string for each voxel
	for y = -180, 180, 90 do
        for z = -180, 180, 90 do
           	table.insert(orientationtable,Vector3.new(x,y,z))
        end
    end
end

wait()
for i,h in pairs(orientationtable) do
	orientationtable2[i] = h
end
wait()
for i,h in pairs(orientationtable) do
	orientationtable3[(h.X .. "," .. h.Y .. "," .. h.Z)] = i
end

function module.Convert(Rotation,mode)
	local returnitem
	if mode == "A" then
		Rotation = (Rotation.X .. "," .. Rotation.Y .. "," .. Rotation.Z)
		returnitem = orientationtable3[Rotation]
	else
		returnitem = orientationtable2[Rotation]
	end
	return returnitem
end

I need to create a table with all of the rotation values and try to keep it as short as possible.

But -180 is the same orientation as 180, i need to be able to get the same number from both of them inside of the table.

There could be 10.000 blocks going through that function, it would cause a massive amount of lag.

One thing I wanted to say real quick, every time you call new() you create a new object, so if you were to do:

local v = {}
v[Vector3.new()] = 1
print(v[Vector3.new()])

the result will actually be nil as these are two different userdata objects, regardless of their contents.
Secondly, if you wanted to “reduce size”, I recommend just making some sort of table where you have something like:

local Direction = {
    "Forward", "Backward", ...
}
for k, v in ipairs(Direction) do Direction[v] = k end --adds Direction.Forward as 1, Direction.Backward as 2...

local Results = {
    [Direction.Forward] = Vector3.new(0,0,1),
    [Direction.Backward] = Vector3.new(0,0,-1), ...
}

and in the block object you can store

print(myobj.Direction) --1 (Direction.Forward)

You can also do other things such as compression of the X,Y,Z pairs or conversion to binary / a single number.

i want to convert it to binary/a single number.

Understanding your question a bit more now, here is a further adaption which maps all Vector3 objects with X, Y, and Z values in the range [-180, 180] in steps of 90 to an integer. The integer they are mapped to ignores their signs, such that the integer mapped from Vector3.new(-90, -90, -90) is the exact same as Vector3.new(90, 90, 90). Also, any mapped integer supplied returns a Vector3 object with X, Y, and Z values in the range [0, 180] in steps of 90:

-- Helper function that, when given two Vector3 values, returns if both Vector3 values are equal.
local function vector3IsEqual(vectorOne, vectorTwo)
	return vectorOne.X == vectorTwo.X
		and vectorOne.Y == vectorTwo.Y
		and vectorOne.Z == vectorTwo.Z;
end

-- Helper function that, when given a Vector3 value, returns a Vector3 where the X, Y, and Z 
-- values are either 0 or positive.
local function vector3ToAbsoluteValues(vector)
	local absX = math.abs(vector.X);
	local absY = math.abs(vector.Y);
	local absZ = math.abs(vector.Z);
	return Vector3.new(absX, absY, absZ);
end

local intToVector3Map = (function()
	local intToVector3Map = {};
	
	-- For every possible Vector3 with X, Y, and Z values in the range [-180, 180] in steps of 90,
    -- map the vector (value) to the integer (index).
	for x = 0, 180, 90 do
		for y = 0, 180, 90 do
			for z = 0, 180, 90 do
				local vector = Vector3.new(x, y, z);
				intToVector3Map[#intToVector3Map + 1] = vector;
			end
		end
	end
	
	return intToVector3Map;
end)();

local vector3ToIntMap = (function()
	local vector3ToIntMap = {};
	
	-- For every possible Vector3 with X, Y, and Z values in the range [-180, 180] in steps of 90, 
    -- map the string representation of the vector (index) to an already mapped integer(value).
	for x = -180, 180, 90 do
		for y = -180, 180, 90 do
			for z = -180, 180, 90 do
				local vector = Vector3.new(x, y, z);
				local vectorAsAbsolute = vector3ToAbsoluteValues(vector);
				for intIndex, mappedVector in ipairs(intToVector3Map) do
					if vector3IsEqual(vectorAsAbsolute, mappedVector) then
						vector3ToIntMap[tostring(vector)] = intIndex;
					end
				end
			end
		end
	end
	
	return vector3ToIntMap;
end)();

-- Addapted to not require the use of __index; no longer can use raw Vector3 values.
-- Opted to use tostring; highly recommend this practice.
print(vector3ToIntMap[tostring(Vector3.new(0, 0, 0))]);
-- Prints "1" (tested in Studio!)

print(intToVector3Map[1]);
-- Prints "0, 0, 0" (tested in Studio!)

-- Proof that signs are ignored:
local intValueOne = vector3ToIntMap[tostring(Vector3.new(-90, 90, -90))];
local intValueTwo = vector3ToIntMap[tostring(Vector3.new(90, -90, 90))];
-- Expect this statement to be true.
print(intValueOne == intValueTwo);
-- Prints "true" (tested in Studio!)

local vector = intToVector3Map[intValueOne];
-- Expect this expression to be equal to Vector3.new(90, 90, 90)
print(vector);
-- Prints "90, 90, 90" (tested in Studio!)

Nvm… seems to by my fault, for some reason it didn’t save the updated number so it didn’t use the right script for the rotation.

It appears that it doesn’t work for all of the rotations.


Most of the blocks are loaded correctly, but some are loaded with the wrong rotations.