如何在godot中获取多边形(凸形或平面)的坐标
How to get coordinates of polygon (convex shape or plane) in godot
我有平面和碰撞形状(凸多边形)
that
如你所见,我的平面和碰撞形状有粗糙度。我需要获取每个多边形的所有坐标和旋转。
我只想生成树
I just want to make tree generation.
您确定不想查询形状与您打算放置树木的特定垂直线相交的位置吗?据推测,您可以为此使用光线投射。
总之,你问的不是这个。你想要所有的坐标。
大概你的MeshInstance
有一个ArrayMesh
(我在这里描述的不适用于原始网格),我们可以在这样的变量中得到它:
var plane:MeshInstance = $Plane
var mesh:ArrayMesh = plane.mesh
然后您将创建一个 MeshDataTool
并从 ArrayMesh
:
填充它
var mdt := MeshDataTool.new()
mdt.create_from_surface(mesh, 0) # surface 0 of the mesh
然后你可以遍历顶点:
for vertex_index in range(mdt.get_vertex_count()):
var vertex:Vector3 = mdt.get_vertex(vertex_index)
print(vertex)
但是,大概您对面孔感兴趣,所以让我们迭代面孔:
for face_index in range(mdt.get_face_count()):
var A := mdt.get_vertex(mdt.get_face_vertex(face_index, 0))
var B := mdt.get_vertex(mdt.get_face_vertex(face_index, 1))
var C := mdt.get_vertex(mdt.get_face_vertex(face_index, 2))
print(A, ", ", B, ", ", C)
请注意,您得到的是模型 space 中的坐标。它们取自 ArrayMesh
,因此不知道应用于使用 ArrayMesh
.
的 MeshInstance
的转换
哦,但这也不是你问的。你想要“所有坐标 和旋转 ”。好吧,我们可以为每个面计算一个法线,它是叉积并归一化:
for face_index in range(mdt.get_face_count()):
var A := mdt.get_vertex(mdt.get_face_vertex(face_index, 0))
var B := mdt.get_vertex(mdt.get_face_vertex(face_index, 1))
var C := mdt.get_vertex(mdt.get_face_vertex(face_index, 2))
var normal := (B - A).cross(C - A).normalized()
print (normal)
除此之外,这可能是颠倒的。我不知道。 你需要(B - A).cross(C - A)
还是(C - A).cross(B - A)
?如果我不在乎,但我知道正常应该是正数y
,我们可以将此作为快速修复:
normal *= sign(normal.y)
这确保 y
始终大于或等于 0
。但是,请注意,如果 y
是 0
,这将使整个向量 0
.
既然我们有了法线,我们就可以算出旋转了。首先我们需要知道我们需要围绕哪个轴旋转未旋转的法线(我认为是Vector3.UP
)以获得法线:
var axis = normal.cross(Vector3.UP).normalize()
而且我们还需要角度:
var angle = Vector3.UP.signed_angle_to(normal, axis)
然后您可以创建表示旋转的变换:
var transform = Transform.IDENTITY.rotated(axis, angle)
我有平面和碰撞形状(凸多边形)
that
如你所见,我的平面和碰撞形状有粗糙度。我需要获取每个多边形的所有坐标和旋转。
我只想生成树
I just want to make tree generation.
您确定不想查询形状与您打算放置树木的特定垂直线相交的位置吗?据推测,您可以为此使用光线投射。
总之,你问的不是这个。你想要所有的坐标。
大概你的MeshInstance
有一个ArrayMesh
(我在这里描述的不适用于原始网格),我们可以在这样的变量中得到它:
var plane:MeshInstance = $Plane
var mesh:ArrayMesh = plane.mesh
然后您将创建一个 MeshDataTool
并从 ArrayMesh
:
var mdt := MeshDataTool.new()
mdt.create_from_surface(mesh, 0) # surface 0 of the mesh
然后你可以遍历顶点:
for vertex_index in range(mdt.get_vertex_count()):
var vertex:Vector3 = mdt.get_vertex(vertex_index)
print(vertex)
但是,大概您对面孔感兴趣,所以让我们迭代面孔:
for face_index in range(mdt.get_face_count()):
var A := mdt.get_vertex(mdt.get_face_vertex(face_index, 0))
var B := mdt.get_vertex(mdt.get_face_vertex(face_index, 1))
var C := mdt.get_vertex(mdt.get_face_vertex(face_index, 2))
print(A, ", ", B, ", ", C)
请注意,您得到的是模型 space 中的坐标。它们取自 ArrayMesh
,因此不知道应用于使用 ArrayMesh
.
MeshInstance
的转换
哦,但这也不是你问的。你想要“所有坐标 和旋转 ”。好吧,我们可以为每个面计算一个法线,它是叉积并归一化:
for face_index in range(mdt.get_face_count()):
var A := mdt.get_vertex(mdt.get_face_vertex(face_index, 0))
var B := mdt.get_vertex(mdt.get_face_vertex(face_index, 1))
var C := mdt.get_vertex(mdt.get_face_vertex(face_index, 2))
var normal := (B - A).cross(C - A).normalized()
print (normal)
除此之外,这可能是颠倒的。我不知道。 你需要(B - A).cross(C - A)
还是(C - A).cross(B - A)
?如果我不在乎,但我知道正常应该是正数y
,我们可以将此作为快速修复:
normal *= sign(normal.y)
这确保 y
始终大于或等于 0
。但是,请注意,如果 y
是 0
,这将使整个向量 0
.
既然我们有了法线,我们就可以算出旋转了。首先我们需要知道我们需要围绕哪个轴旋转未旋转的法线(我认为是Vector3.UP
)以获得法线:
var axis = normal.cross(Vector3.UP).normalize()
而且我们还需要角度:
var angle = Vector3.UP.signed_angle_to(normal, axis)
然后您可以创建表示旋转的变换:
var transform = Transform.IDENTITY.rotated(axis, angle)