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.
i have gone with my own system as i was confused and i thought it was possible to get only 64 numbers from the orientation. its working now.