diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e3d32c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.import/* \ No newline at end of file diff --git a/Main.tscn b/Main.tscn new file mode 100644 index 0000000..b4431a5 --- /dev/null +++ b/Main.tscn @@ -0,0 +1,55 @@ +[gd_scene load_steps=7 format=2] + +[ext_resource path="res://Scripts/Main.gd" type="Script" id=1] + +[sub_resource type="SpatialMaterial" id=1] +albedo_color = Color( 0.0627451, 0.8, 0.25098, 1 ) + +[sub_resource type="CubeMesh" id=2] +material = SubResource( 1 ) + +[sub_resource type="BoxShape" id=5] + +[sub_resource type="SpatialMaterial" id=3] +albedo_color = Color( 0.592157, 0.905882, 0.0862745, 1 ) + +[sub_resource type="CubeMesh" id=4] +material = SubResource( 3 ) + +[node name="Main" type="Spatial"] +transform = Transform( 1, 0, 0, 0, 0.99977, 0.021431, 0, -0.021431, 0.99977, 0, 0, 0 ) +script = ExtResource( 1 ) +show_wireframe = false +show_axes = false +show_face_normals = false + +[node name="Meshes" type="Node" parent="."] + +[node name="Cube" type="MeshInstance" parent="Meshes"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.07597, 0 ) +mesh = SubResource( 2 ) +material/0 = null + +[node name="StaticBody" type="StaticBody" parent="Meshes/Cube"] + +[node name="CollisionShape" type="CollisionShape" parent="Meshes/Cube/StaticBody"] +shape = SubResource( 5 ) + +[node name="Floor" type="MeshInstance" parent="Meshes"] +transform = Transform( 6.88346, 0, 0, 0, 0.0447118, 0, 0, 0, 7.16078, 0, 0, 0 ) +mesh = SubResource( 4 ) +material/0 = null + +[node name="Lights" type="Node" parent="."] + +[node name="DirectionalLight" type="DirectionalLight" parent="Lights"] +transform = Transform( 1, 0, 0, 0, 0.778528, 0.62761, 0, -0.62761, 0.778528, 0, 3.77816, 3.77808 ) + +[node name="CameraAnchor" type="Spatial" parent="."] +transform = Transform( 0.391454, -0.0197208, 0.919986, 0.0197208, 0.999721, 0.0130388, -0.919987, 0.0130388, 0.391734, 0, 0, 0 ) + +[node name="Camera" type="Camera" parent="CameraAnchor"] +transform = Transform( 0.871787, -0.177322, 0.456666, -9.31323e-10, 0.932191, 0.361967, -0.489885, -0.315558, 0.812672, 2.14561, 3.89777, 4.89912 ) +[connection signal="input_event" from="Meshes/Cube/StaticBody" to="." method="_on_StaticBody_input_event"] +[connection signal="mouse_entered" from="Meshes/Cube/StaticBody" to="." method="_on_StaticBody_mouse_entered"] +[connection signal="mouse_exited" from="Meshes/Cube/StaticBody" to="." method="_on_StaticBody_mouse_exited"] diff --git a/README.md b/README.md index f915b74..78efc56 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ -# MeshManipulation \ No newline at end of file +# GODOT Mesh Manipulation + +I'm following along this series https://www.youtube.com/playlist?list=PLWWV0KoRkFHAMR27dAy3YsJHbkCGpIuAF I did skip 01 so ...yeah. Only thing so far I noticed is that I didn't import in anything from Blender, I just created a MeshInstance that had a cube body. Didn't even know it was different till it was brought up way later. + +Started branching at the beginning of video 08. \ No newline at end of file diff --git a/Scripts/Main.gd b/Scripts/Main.gd new file mode 100644 index 0000000..83419f7 --- /dev/null +++ b/Scripts/Main.gd @@ -0,0 +1,156 @@ +extends Spatial + +var is_rotate_enabled = false +var is_zoom_enabled = false +var input_start_position = Vector2() +var camera_anchor +var rotation_speed = 0.2 +var zoom_step = 0.002 +var camera +var zoom_min = 3 + +export var show_wireframe = true +export var show_axes = true +export var show_face_normals = true + +func _input(event): + if event.is_action_pressed("ui_rotate"): + is_rotate_enabled = true + input_start_position = get_viewport().get_mouse_position() + if event.is_action_released("ui_rotate"): + is_rotate_enabled = false + + if event.is_action_pressed("ui_zoom"): + is_zoom_enabled = true + input_start_position = get_viewport().get_mouse_position() + if event.is_action_released("ui_zoom"): + is_zoom_enabled = false + + if event.is_action_pressed("ui_exit"): + get_tree().quit() + + if event is InputEventMouse: + var delta = input_start_position - event.get_position() + if is_rotate_enabled: + print("Delta x:", delta.x, " y: ", delta.y) + camera_anchor.rotate_y(deg2rad(delta.x) * rotation_speed) + #camera_anchor.rotate_z(deg2rad(delta.y) * rotation_speed) # Hmm + input_start_position = event.get_position() + elif is_zoom_enabled: + var camera_to_anchor = camera_anchor.get_global_transform().origin - camera.get_global_transform().origin + var length = camera_to_anchor.length() + if(length > zoom_min): + camera.global_translate((delta.y * zoom_step) * camera_to_anchor) + input_start_position = event.get_position() + +func _ready(): + camera_anchor = get_node("CameraAnchor") + camera = get_node("CameraAnchor/Camera") + + if show_wireframe: + drawWireframe() + if show_axes: + drawAxes() + if show_face_normals: + drawSurfaceNormals() + +func drawSurfaceNormals(): + var cubeMeshInstance = get_node("Meshes/Cube") + var cubeMesh = cubeMeshInstance.get_mesh() + var vertices = cubeMesh.get_faces() + var arrayMesh = ArrayMesh.new() + var arrays = [] + arrays.resize(ArrayMesh.ARRAY_MAX) + arrays[ArrayMesh.ARRAY_VERTEX] = vertices + arrayMesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) + var meshDataTool = MeshDataTool.new() + meshDataTool.create_from_surface(arrayMesh, 0) + + var ig = ImmediateGeometry.new() + var sm = SpatialMaterial.new() + sm.flags_unshaded = true + sm.vertex_color_use_as_albedo = true + ig.material_override = sm + + ig.begin(Mesh.PRIMITIVE_LINES) + ig.set_color(Color.white) + + var i = 0 + while i < meshDataTool.get_face_count(): + var verticesIndex = i * 3 + var a = vertices[verticesIndex] + var b = vertices[verticesIndex + 1] + var c = vertices[verticesIndex + 2] + var face_center = (a+b+c)/3 + + ig.add_vertex(face_center) + ig.add_vertex(meshDataTool.get_face_normal(i) + face_center) + i += 1 + + ig.end() + cubeMeshInstance.add_child(ig) + +func drawAxes(): + var axisGeom = ImmediateGeometry.new() + var axisMaterial = SpatialMaterial.new() + var axisLength = 10 + axisMaterial.flags_unshaded = true + axisMaterial.vertex_color_use_as_albedo = true + axisMaterial.flags_no_depth_test = true # Makes it so the lines are drawn over the earlier added objects + axisGeom.material_override = axisMaterial; + axisGeom.begin(Mesh.PRIMITIVE_LINES) + + axisGeom.set_color(Color.red) + axisGeom.add_vertex(Vector3(0,0,0)) + axisGeom.add_vertex(Vector3(axisLength,0,0)) + axisGeom.set_color(Color.green) + axisGeom.add_vertex(Vector3(0,0,0)) + axisGeom.add_vertex(Vector3(0,axisLength,0)) + axisGeom.set_color(Color.blue) + axisGeom.add_vertex(Vector3(0,0,0)) + axisGeom.add_vertex(Vector3(0,0,axisLength)) + + axisGeom.end() + add_child(axisGeom) + +func drawWireframe(): + var cubeMeshInstance = get_node("Meshes/Cube") + var cubeMesh = cubeMeshInstance.get_mesh() + + var ig = ImmediateGeometry.new() + var sm = SpatialMaterial.new() + sm.flags_unshaded = true + sm.vertex_color_use_as_albedo = true + ig.material_override = sm + + ig.begin(Mesh.PRIMITIVE_LINES) + ig.set_color(Color.yellow) + + cubeMesh.create_outline(1.0) + var vertices = cubeMesh.get_faces() + + var i = 0 + print("Size: %s" % vertices.size()) + while i < vertices.size(): + ig.add_vertex(vertices[i]) + ig.add_vertex(vertices[i+1]) + ig.add_vertex(vertices[i+1]) + ig.add_vertex(vertices[i+2]) + ig.add_vertex(vertices[i+2]) + ig.add_vertex(vertices[i]) + i += 3 + + ig.end() + var sf = 1.005 + ig.set_scale(Vector3(sf, sf, sf)) + cubeMeshInstance.add_child(ig) + +func _on_StaticBody_mouse_entered(): + print("In cube") + +func _on_StaticBody_mouse_exited(): + print("Out cube") + +func _on_StaticBody_input_event(camera, event, click_position, click_normal, shape_idx): + if event.is_action_pressed("left_mouse"): + print("Pos ", click_position) diff --git a/default_env.tres b/default_env.tres new file mode 100644 index 0000000..20207a4 --- /dev/null +++ b/default_env.tres @@ -0,0 +1,7 @@ +[gd_resource type="Environment" load_steps=2 format=2] + +[sub_resource type="ProceduralSky" id=1] + +[resource] +background_mode = 2 +background_sky = SubResource( 1 ) diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..c98fbb6 Binary files /dev/null and b/icon.png differ diff --git a/icon.png.import b/icon.png.import new file mode 100644 index 0000000..96cbf46 --- /dev/null +++ b/icon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.png" +dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..415a6be --- /dev/null +++ b/project.godot @@ -0,0 +1,65 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=4 + +_global_script_classes=[ ] +_global_script_class_icons={ + +} + +[application] + +config/name="MeshManipulation" +run/main_scene="res://Main.tscn" +config/icon="res://icon.png" + +[input] + +ui_exit={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"unicode":0,"echo":false,"script":null) + ] +} +ui_rotate={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777240,"unicode":0,"echo":false,"script":null) +, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":3,"pressed":false,"doubleclick":false,"script":null) + ] +} +ui_zoom={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"unicode":0,"echo":false,"script":null) + ] +} +ui_pan={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777238,"unicode":0,"echo":false,"script":null) + ] +} +ui_zoom_in={ +"deadzone": 0.5, +"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":4,"pressed":false,"doubleclick":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777349,"unicode":0,"echo":false,"script":null) + ] +} +ui_zoom_out={ +"deadzone": 0.5, +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777347,"unicode":0,"echo":false,"script":null) +, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":5,"pressed":false,"doubleclick":false,"script":null) + ] +} +left_mouse={ +"deadzone": 0.5, +"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"pressed":false,"doubleclick":false,"script":null) + ] +} + +[rendering] + +environment/default_environment="res://default_env.tres"