2d_shape.gd 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. extends Position3D
  2. # Created by Danil (2020+) https://github.com/danilw
  3. # The MIT License
  4. export(float) var shape_size #=0.2 # collision shape size
  5. export(int) var sec_to_record #=13 # seconds to record, default fps is 60
  6. export(int) var box_size #=20 # recording box size, min is 1
  7. const default_fps=60
  8. # script spawn RigidBody base on 2d tile map
  9. # and save each RigidBody position every fract
  10. # when all Frames recorded frames saved to png file(8bit)
  11. # data in saved png file is 16-bit values saved in every two 8-bit pixels (rgb=xyz position)
  12. # using 8bit png because WebGl does not support 16bit texture format
  13. const elems=256 # elements to spawn
  14. #const max_image_size=Vector2(2048*2,2048) # 4096*2048 texture
  15. const max_image_size=Vector2(1024*2,1024) # for WebGL because WebGL GLES2 may not support 4k textures
  16. const max_frames=int(max_image_size.y*max_image_size.y)/elems
  17. # 4096*2048 texture=16384 frames, 4 min 33 sec on 60fps
  18. # 2048*1024 texture=4096 frames, 68 sec on 60fps
  19. var frames_to_rec:int=1
  20. var extra_elems:int=0
  21. var image_size:Vector2=Vector2()
  22. onready var tilemap=get_node("2d/TileMap")
  23. onready var rigbody=get_node("body/RigidBody")
  24. onready var spawn=get_node("spawn")
  25. onready var timer_text=get_node("../UI/timer")
  26. onready var saved_text=get_node("../UI/saved")
  27. func _ready():
  28. frames_to_rec=min(sec_to_record*default_fps,max_frames)
  29. image_size=Vector2(min(ceil(sqrt(frames_to_rec*elems))*2,max_image_size.x),min(ceil(sqrt(frames_to_rec*elems)),max_image_size.y))
  30. extra_elems=int((image_size.x/2)*image_size.y)-frames_to_rec*elems
  31. var tiles=tilemap.get_used_cells_by_id(0)
  32. for a in range(elems):
  33. var idx=a%tiles.size()
  34. var pos=tiles[idx]
  35. var dupl=rigbody.duplicate(0)
  36. dupl.translation.z=pos.x*shape_size+0.0015
  37. dupl.translation.y=-pos.y*shape_size+0.0015
  38. dupl.translation.x=shape_size*(a/tiles.size())+0.001*(1-2*(int(pos.y)%2))
  39. spawn.add_child(dupl)
  40. rigbody.queue_free()
  41. var iFrame:int=0
  42. var data=[]
  43. func _process(delta):
  44. timer_text.text="animation progress: "+format_num(int((float(iFrame)/frames_to_rec)*100))+" %"
  45. if(frames_to_rec>iFrame):
  46. var tpos=[]
  47. for a in range(spawn.get_child_count()):
  48. var tpos_val=spawn.get_child(a).global_transform.origin
  49. tpos.append(tpos_val)
  50. data.append(tpos)
  51. else:
  52. on_save()
  53. set_process(false)
  54. iFrame+=1
  55. func on_save():
  56. var path = OS.get_executable_path().get_base_dir().plus_file("frame_capture")
  57. var dir = Directory.new()
  58. dir.make_dir(path)
  59. print("save to "+str(path))
  60. var extra_data=[]
  61. for a in range(extra_elems):
  62. extra_data.append(Vector3())
  63. data.append(extra_data)
  64. var data_array=[]
  65. for a in range(data.size()):
  66. for b in range(data[a].size()):
  67. var tpos=data[a][b]
  68. tpos=tpos+Vector3(box_size/2.0,0,box_size/2.0)
  69. data_array.append(int(clamp((tpos.x/box_size),0.0,1.0)*65536.0)% 256)
  70. data_array.append(int(clamp((tpos.x/box_size),0.0,1.0)*65536.0)/ 256)
  71. data_array.append(int(clamp((tpos.y/box_size),0.0,1.0)*65536.0)% 256)
  72. data_array.append(int(clamp((tpos.y/box_size),0.0,1.0)*65536.0)/ 256)
  73. data_array.append(int(clamp((tpos.z/box_size),0.0,1.0)*65536.0)% 256)
  74. data_array.append(int(clamp((tpos.z/box_size),0.0,1.0)*65536.0)/ 256)
  75. var byte_array = PoolByteArray(data_array)
  76. var img = Image.new()
  77. img.create_from_data(image_size.x, image_size.y, false, Image.FORMAT_RGB8, byte_array)
  78. img.save_png(path.plus_file("capture2.png"))
  79. print("done")
  80. saved_text.visible=true
  81. func format_num(num):
  82. var a=str(num)
  83. if(a.length()<2):
  84. a="0"+a
  85. return a