Advertisement
opponent019

UV_position_on_mesh

Oct 4th, 2023
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
GDScript 3.30 KB | Source Code | 0 0
  1. extends Node
  2.  
  3. var meshtool
  4. var mesh
  5. var mesh_instance
  6.  
  7. var transform_vertex_to_global = true
  8.  
  9. var _face_count := 0
  10. var _world_normals := PackedVector3Array()
  11. var _world_vertices := []
  12. var _local_face_vertices := []
  13.  
  14. func set_mesh(_mesh_instance):
  15.     mesh_instance = _mesh_instance
  16.     mesh = _mesh_instance.mesh
  17.  
  18.     meshtool = MeshDataTool.new()
  19.     meshtool.create_from_surface(mesh, 0)  
  20.    
  21.     _face_count = meshtool.get_face_count()
  22.     _world_normals.resize(_face_count)
  23.  
  24.     _load_mesh_data()
  25.  
  26. func _resize_pools():
  27.     pass
  28.  
  29. func _load_mesh_data():
  30.     for idx in range(_face_count):
  31.         #_world_normals[idx] = mesh_instance.global_transform.basis.xform(meshtool.get_face_normal(idx))
  32.         _world_normals[idx] = mesh_instance.global_transform.basis * meshtool.get_face_normal(idx)
  33.        
  34.         var fv1 = meshtool.get_face_vertex(idx, 0)
  35.         var fv2 = meshtool.get_face_vertex(idx, 1)
  36.         var fv3 = meshtool.get_face_vertex(idx, 2)
  37.        
  38.         _local_face_vertices.append([fv1, fv2, fv3])    
  39.        
  40.         _world_vertices.append([
  41.           mesh_instance.global_transform * meshtool.get_vertex(fv1),
  42.           mesh_instance.global_transform * meshtool.get_vertex(fv2),
  43.           mesh_instance.global_transform * meshtool.get_vertex(fv3),
  44.         ])
  45.  
  46. #func _ready():
  47. #   set_mesh(self.get_parent())
  48. #   _load_mesh_data()
  49.    
  50. func get_face(point, normal, epsilon = 0.2):
  51.     for idx in range(_face_count):
  52.         var world_normal = _world_normals[idx]
  53.    
  54.         if !equals_with_epsilon(world_normal, normal, epsilon):
  55.             continue
  56.    
  57.         var vertices = _world_vertices[idx]    
  58.        
  59.         var bc = is_point_in_triangle(point, vertices[0], vertices[1], vertices[2])    
  60.         if bc:
  61.             return [idx, vertices, bc]
  62.     return [-6, -6, -6] # using null was giving issues
  63.  
  64. func get_uv_coords(point, normal, transform = true):
  65. # Gets the uv coordinates on the mesh given a point on the mesh and normal
  66. # these values can be obtained from a raycast
  67.     transform_vertex_to_global = transform
  68.    
  69.     var face : Array = get_face(point, normal)
  70.     if face == [-6, -6, -6]:
  71.         return null
  72.    
  73.     var bc = face[2]
  74.    
  75.     var uv1 = meshtool.get_vertex_uv(_local_face_vertices[face[0]][0])
  76.     var uv2 = meshtool.get_vertex_uv(_local_face_vertices[face[0]][1])
  77.     var uv3 = meshtool.get_vertex_uv(_local_face_vertices[face[0]][2])
  78.    
  79.     return (uv1 * bc.x) + (uv2 * bc.y) + (uv3 * bc.z)  
  80.  
  81. func equals_with_epsilon(v1, v2, epsilon):
  82.     if (v1.distance_to(v2) < epsilon):
  83.         return true
  84.     return false
  85.  
  86. func cart2bary(p : Vector3, a : Vector3, b : Vector3, c: Vector3) -> Vector3:
  87.     var v0 := b - a
  88.     var v1 := c - a
  89.     var v2 := p - a
  90.     var d00 := v0.dot(v0)
  91.     var d01 := v0.dot(v1)
  92.     var d11 := v1.dot(v1)
  93.     var d20 := v2.dot(v0)
  94.     var d21 := v2.dot(v1)
  95.     var denom := d00 * d11 - d01 * d01
  96.     var v = (d11 * d20 - d01 * d21) / denom
  97.     var w = (d00 * d21 - d01 * d20) / denom
  98.     var u = 1.0 - v - w
  99.     return Vector3(u, v, w)
  100.  
  101. func transfer_point(from : Basis, to : Basis, point : Vector3) -> Vector3:
  102.     return (to * from.inverse()) * point
  103.     #return (to * from.inverse()).xform(point)
  104.  
  105. func bary2cart(a : Vector3, b : Vector3, c: Vector3, barycentric: Vector3) -> Vector3:
  106.     return barycentric.x * a + barycentric.y * b + barycentric.z * c
  107.  
  108. func is_point_in_triangle(point, v1, v2, v3):
  109.     var bc = cart2bary(point, v1, v2, v3)  
  110.  
  111.     if (bc.x < 0 or bc.x > 1) or (bc.y < 0 or bc.y > 1) or (bc.z < 0 or bc.z > 1):
  112.         return null
  113.  
  114.     return bc
Tags: Godot godot 4
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement