Hello, I am trying to get a vertex’s position but for some reason the position seems to have some sort of offset or something.
For example: (This is example code not my real code)
local NewEditMesh = Instance.new("EditableMesh")
for I, V in pairs(NewEditMesh:GetVertices()) do
NewEditMesh:GetPosition(V) -- Doesnt return the actual position.
end
The position also seems to be kind of scaled up for some reason.
Sorry if you had a hard time understanding me, English isn’t my first language.
According to the documentation, the position returned is in LocalSpace. You can simply convert it into WorldSpace to get the proper position:
local NewEditMesh = Instance.new("EditableMesh")
for I, V in pairs(NewEditMesh:GetVertices()) do
local LocalPos = NewEditMesh:GetPosition(V)
local RealPos = NewEditMesh.CFrame:PointToWorldSpace(LocalPos)
end
Ah right Editable Mesh isn’t a meshpart
Looking at it closer the EditableMesh contains offset and scale that we can try use.
local NewEditMesh = Instance.new("EditableMesh")
for I, V in pairs(NewEditMesh:GetVertices()) do
local LocalPos = NewEditMesh:GetPosition(V)
local RealPos = ParentPart.CFrame:PointToWorldSpace(LocalPos * NewEditMesh.Scale + NewEditMesh.Offset) -- Something like thiis possibly.
end
I don’t have studio open on me right now so I’ll try tinker with it more accurately once I’m on
Alright I had some time to look at it closer. Turns out offset and scale basically do nothing so the real WorldPosition is as simple as:
local WorldPosition = Part.CFrame:PointToWorldSpace(Mesh:GetPosition(index) * Part.Size)
And going back to local space can be done like so:
local LocalPosition = Part.CFrame:PointToObjectSpace(WorldPosition) / Part.Size
So as a demonstration I wrote a simple test to morph a mesh when it is close to a point in worldspace.
This is the script I wrote:
local RunService = game:GetService("RunService")
local ID = "http://www.roblox.com/asset/?id=152974584"
local Part = script.Parent
local Mesh = game:GetService("AssetService"):CreateEditableMeshAsync(ID)
Mesh.Parent = Part
local BackupMesh = Mesh:Clone()
local Attachment = Part.ExampleAttachment
local PullDistance = 10
RunService.Heartbeat:Connect(function(delta)
local TargetPosition = Attachment.WorldPosition
local LocalPosition = Part.CFrame:PointToObjectSpace(TargetPosition) / Part.Size
for i,v in Mesh:GetVertices() do
local Pos = BackupMesh:GetPosition(v)
local WorldPosition = Part.CFrame:PointToWorldSpace(Pos * Part.Size)
local Distance = WorldPosition - TargetPosition
if Distance.Magnitude < PullDistance then
local Weight = math.clamp(1-(Distance.Magnitude / PullDistance), 0, 1)
local NewPosition = Pos:Lerp(LocalPosition, Weight)
Mesh:SetPosition(v, NewPosition)
else
Mesh:SetPosition(v, Pos)
end
end
end)
And this is what the workspace looks like:
EDIT: Backup of the original editable mesh was needed so the vertices know where to go back to
It’s not working for me for some reason, I am trying to make a simple cloth system, and I am going to use rope and parts to do this, I want to make a vertex be at the position of a part.
My code:
RunService.Heartbeat:Connect(function()
for VerticeI, Vertice in pairs(NewCloth.PhysicsVertices) do -- Every physics Vertex is a table that has the vertex id and a part that the vertex position must be at.
local LocalPosition = NewCloth.ClothPart.CFrame:PointToObjectSpace(Vertice.Part.Position) * (NewCloth.ClothPart.Size / 2)
if VerticeI % 100 == 0 then
print(LocalPosition) -- For debuging.
end
NewCloth.ClothEdit:SetPosition(Vertice.Vertice, LocalPosition)
end
end)
Edit: It works kinda, but the vertex seems to be like slow, sorry I am very bad at explaining.
Sorry, I scrapped the project I was working on, but now I am facing the same problem again,
My old solution only worked on some of the meshes, I can’t find a solution that works for all meshes though,
for I, Vertex in pairs(Vertices) do
local VertexDrone:BasePart = AvailableDrones[VertexI]
if VertexDrone then
pcall(function()
local UVPos = EditMesh:GetUV(Vertex)
local VertexColors = UVEdit:ReadPixels(UVPos * (UVEdit.Size - Vector2.one), Vector2.one)
local VertexColor = Color3.new(VertexColors[1], VertexColors[2], VertexColors[3])
local VertexPos = EditMesh:GetPosition(Vertex)
local WorldPos = Part.CFrame:PointToWorldSpace(VertexPos * Part.Size)
VertexDrone.Color = VertexColor
VertexDrone.DroneLight.Color = VertexColor
VertexDrone.BodyPosition.Position = WorldPos
if VertexI % 50 == 0 then -- Used for debugging.
end
VertexDrone.Parent = DroneFolder.UnAvailable
end)
end
VertexI += 1
end
Also I am trying to make flying parts (drones) to fly to every vertex in a mesh.
No problem! You were right that for some reason it didn’t work for the mesh you provided. I was able to get it working by slightly changing the code to account the original size of the mesh:
local Position = EditableMesh:GetPosition(vertexId)
local WorldPosition = Mesh.CFrame:PointToWorldSpace(Position * Mesh.Size / Mesh.MeshSize)