Getting vertex's position doesn't return the actual world position

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.

I tried searching up for a solution but because this API is new I couldn’t find anything.

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
2 Likes

It’s saying that CFrame is not a valid member of EditableMesh.

I tried using the mesh part’s CFrame but that didn’t work, the positions seems to be more spread apart and scaled up.

Ah right Editable Mesh isn’t a meshpart :smiley:
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 :smiley:

1 Like

I fixed it by doing:

local RealPos = Part.CFrame:PointToWorldSpace(LocalPos / (Part.Size / 2))

But I am not sure how to do the opposite, I want the vertex to follow a part and I need to turn worldspace into localspace.

Opposite could be done with CFrame:PointToObjectSpace

1 Like

It’s not working for me can you give me a code example?

Sure once I get on studio I can try tinker with this.

1 Like

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:
kuva

EDIT: Backup of the original editable mesh was needed so the vertices know where to go back to

1 Like

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.

Would you be able to provide an example place file of the specific scenario you are having issues with?

1 Like

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,

The code I made above should work with all meshes. If you have some mesh it doesn’t work with, let me know and I can take a look at it.

This mesh right here: https://create.roblox.com/store/asset/17407185228/MeshTest

Also this is the new code of my new project:

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.

I tried using Mesh.Scale and Mesh.Offset but that didn’t work, and I don’t even use these properties.

Is this a bug or something? because this API is new and I can’t find any solutions to this problem.

I tried checking your mesh yesterday but it appears to be private :smiley: I can take another look today if you make the mesh public

Sorry, I forgot to make it public lol.
Now it should be public hopefully, I am very sorry for that lol.

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)

Hope this helps :smiley:

1 Like