Add addon to support grid maps and tweak it to support collision and materials

This commit is contained in:
Spencer Killen 2024-05-25 18:27:35 -06:00
parent ef8553fe45
commit f9847bcb37
Signed by: sjkillen
GPG Key ID: 3AF3117BA6FBB75B
18 changed files with 399 additions and 1 deletions

View File

@ -0,0 +1,24 @@
# this file shouldnt be in your project. If you have it, remove it.
# Godot 4+ specific ignores
.godot/
# Godot-specific ignores
.import/
export.cfg
export_presets.cfg
# Imported translations (automatically generated from CSV files)
*.translation
# Mono-specific ignores
.mono/
data_*/
mono_crash.*.json
# Ignore any import metadata files
*.import
# Ignore the generated project files
project.godot

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Zincles
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,26 @@
![GLTF2MeshLib](addons/gltf2meshlib/gltf2meshlib.svg)
# GLTF2MeshLib
This plugin allows you to import gltf/glb models as MeshLibrary, which saves a lot of time compared to manual importing.
In the manual case, you would need to create an inherited scene of the gltf scene, reparent all mesh nodes (otherwise only the first mesh will be exported), and manually "export as MeshLibrary".
With this plugin, you can simply drag and drop gltf/glb files into the editor, select "GLTF To MeshLibrary" in the import settings, and it will automatically import your gltf/glb as a MeshLibrary. This allows you to see instant changes after any modification of the gltf file.
In my case, I used models made with Blockbench, exported as gltf, and imported into Godot with this plugin, and it seems to work fine as I expected. I am using Godot 4.3.
If you encounter any problems, or if you have any suggestions, please let me know in the Issues.
## Installation
you can simply install this plugin in Godot's built-in asset library.
If you prefers manual installation, you can download the zip file from the release page, and extract it to the root folder of your project.
## Contributors
This plugin is made by Zincles with help of many cool people( but I havent asked them if they are okay with me listing their names here, sorry :p )
## License
License under MIT License.

View File

@ -0,0 +1,16 @@
@tool
extends EditorPlugin
var importer: EditorImportPlugin
# Init importer
func _enter_tree():
importer = preload("importer.gd").new()
add_import_plugin(importer)
# deactivate importer
func _exit_tree():
remove_import_plugin(importer)
importer = null

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="512"
height="512"
viewBox="0 0 512 512"
version="1.1"
id="svg1"
xml:space="preserve"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
sodipodi:docname="gltf2meshlibrary.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
inkscape:zoom="1.118665"
inkscape:cx="310.19116"
inkscape:cy="176.10276"
inkscape:window-width="1920"
inkscape:window-height="1006"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1"
inkscape:current-layer="layer1-5" /><defs
id="defs1" /><g
inkscape:label="图层 1"
inkscape:groupmode="layer"
id="layer1"><g
inkscape:label="图层 1"
id="layer1-5"
transform="matrix(16.547488,0,0,16.547488,-2.9824816,-0.61957474)"><path
d="m 19.735535,16.166265 a 2,2 0 1 0 -2.729,2.73 v 6.542 a 2,2 0 1 0 2.73,2.728 h 2.27 v -2 h -2.272 a 2,2 0 0 0 -0.728,-0.73 v -5.856 l 3,3 v -0.414 a 2,2 0 0 1 0.809,-1.606 l -2.395,-2.394 h 5.858 a 2,2 0 0 0 0.728,0.73 v 1.27 a 2,2 0 0 1 1,0.271 2,2 0 0 1 1,-0.271 v -1.272 a 2,2 0 1 0 -2.73,-2.728 z m 4.271,6 v 7 h 5 a 1,1 0 0 0 1,-1 v -5 a 1,1 0 0 0 -1,-1 v 4 l -1,-1 -1,1 v -4 z"
fill="#ffca5f"
id="path1-1" /><path
style="fill:#43c9ff;fill-opacity:1;stroke:#000000;stroke-width:0.370394;stroke-linejoin:bevel;stroke-opacity:0;paint-order:stroke fill markers"
d="m 17.005663,6.7540684 c 1.071463,-0.6110523 3.220595,-1.4841904 5.82854,-1.1776723 1.814953,0.3573218 2.890602,1.0963645 3.239506,3.5480427 -0.02911,1.3022252 -0.181802,2.4506152 -0.395061,3.3580232 l 2.508642,0.07901 -3.713581,1.423709 -3.599514,-1.412139 2.478551,-0.102153 0.114308,-2.281361 C 23.586885,8.3599342 23.185793,8.2816739 22.435922,7.9356902 20.554648,7.5203675 19.741504,8.474568 17.721534,9.3634018 Z"
id="path2"
sodipodi:nodetypes="cccccccccccc" /><path
id="path3"
style="fill:#fc7f7f;fill-opacity:1;stroke:#000000;stroke-width:0.569312;stroke-linejoin:bevel;stroke-opacity:0;paint-order:stroke fill markers"
d="m 3.9722294,8.8827223 c 0.02561,3.6860667 0.2529479,3.8413417 -2.2026973,3.9046227 l 0.010339,1.978061 c 1.736389,-0.01271 3.3864522,-0.19064 3.411599,-2.135238 L 5.162239,2.632181 C 1.2457168,1.9779297 0.0809414,8.2208891 3.9722294,8.8827223 Z m 0,-4.5072141 v 2.9189872 c -0.2362176,0 -0.4305566,-0.089838 -0.5831505,-0.2379933 C 2.6757331,6.3639058 2.8746686,4.3968542 3.9722294,4.3755082 Z"
sodipodi:nodetypes="ccccccccsc" /><path
style="fill:#fc7f7f;fill-opacity:1;stroke:#000000;stroke-width:0.514321;stroke-linejoin:bevel;stroke-opacity:0;paint-order:stroke fill markers"
d="m 6.1629306,2.6095764 0.062874,8.8860846 c 0.056295,2.505297 0.7366282,2.914364 2.3217009,3.098038 l -0.043692,-1.564585 c -1.0411389,-0.0048 -1.0249838,-0.09607 -1.030107,-1.672279 L 7.4973872,2.6193637 C 7.059816,2.5991761 6.6895369,2.5936853 6.1629306,2.6095764 Z"
id="path4"
sodipodi:nodetypes="ccccccc" /><path
style="fill:#fc7f7f;fill-opacity:1;stroke:#000000;stroke-width:0.569312;stroke-linejoin:bevel;stroke-opacity:0;paint-order:stroke fill markers"
d="M 9.9783564,4.2170178 H 9.3017678 v 1.5882268 h 0.7463162 l 0.0632,6.1244494 c 0.014,3.173018 1.112034,2.617336 2.454064,2.58844 l -0.03316,-1.263427 c -0.950744,0.03613 -1.065654,-0.03602 -1.092104,-1.307465 L 11.303656,5.8052446 h 0.779162 l -0.02723,-1.5706793 -0.844901,-0.017547 0.02325,-1.5882268 H 9.9086308 Z"
id="path16"
sodipodi:nodetypes="ccccccccccccccc" /><path
style="fill:#fc7f7f;fill-opacity:1;stroke:#000000;stroke-width:0.59477;stroke-linejoin:bevel;stroke-opacity:0;paint-order:stroke fill markers"
d="m 15.685035,2.6184771 c -1.772451,-0.024584 -2.533408,0.092376 -2.474126,1.7336615 l 0.03593,10.1345404 1.194446,-0.0043 0.0034,-6.2860931 1.257948,-0.044391 -0.01294,-1.1717121 -1.314187,0.02733 c -0.07499,-3.1158914 -0.108175,-3.157718 1.293388,-3.1188954 z"
id="path17"
sodipodi:nodetypes="cccccccccc" /><g
transform="matrix(0.0128125,0,0,0.0128125,1.5242337,15.574234)"
id="g7"><g
fill="#ffffff"
id="g4"><path
d="m 105,673 v 33 q 407,354 814,0 v -33 z"
id="path1" /><path
d="m 105,673 152,14 q 12,1 15,14 l 4,67 132,10 8,-61 q 2,-11 15,-15 h 162 q 13,4 15,15 l 8,61 132,-10 4,-67 q 3,-13 15,-14 L 919,673 V 427 q 30,-39 56,-81 -35,-59 -83,-108 -43,20 -82,47 -40,-37 -88,-64 7,-51 8,-102 -59,-28 -123,-42 -26,43 -46,89 -49,-7 -98,0 -20,-46 -46,-89 -64,14 -123,42 1,51 8,102 -48,27 -88,64 -39,-27 -82,-47 -48,49 -83,108 26,42 56,81 z m 0,33 v 39 c 0,276 813,276 814,0 v -39 l -134,12 -5,69 q -2,10 -14,13 l -162,11 q -12,0 -16,-11 L 578,735 H 446 l -10,65 q -4,11 -16,11 L 258,800 q -12,-3 -14,-13 l -5,-69 z"
fill="#478cbf"
id="path2-2" /><path
d="m 483,600 c 0,34 58,34 58,0 v -86 c 0,-34 -58,-34 -58,0 z"
id="path3-0" /><circle
cx="725"
cy="526"
r="90"
id="circle3" /><circle
cx="299"
cy="526"
r="90"
id="circle4" /></g><g
fill="#414042"
id="g6"><circle
cx="307"
cy="532"
r="60"
id="circle5" /><circle
cx="717"
cy="532"
r="60"
id="circle6" /></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -0,0 +1,138 @@
@tool
class_name GLTF2MeshLibraryImporter
extends EditorImportPlugin
#region plugin_definitions
# In my case the plugin works fine by default.
# If you have any suggestions, please let me know in Github Issues.
func _get_importer_name():
return "zincles.gltf2meshlib"
func _get_visible_name():
return "GLTF To MeshLibrary"
func _get_recognized_extensions():
return ["gltf", "glb"]
func _get_save_extension():
return "meshlib"
func _get_resource_type():
return "MeshLibrary"
func _get_preset_count():
return 1
func _get_preset_name(preset_index):
return "Default"
func _get_import_options(path, preset_index):
#return [{"name": "my_option", "default_value": false}]
return []
func _get_option_visibility(path, option_name, options):
return true
func _get_import_order():
return 9999
#endregion
#region importer_logics.
func _is_ImporterMeshInstance3D(node: Node) -> bool:
#print("Node: ", node)
if is_instance_of(node, ImporterMeshInstance3D):
return true
return false
# Found all nodes, Pack them into an Array.
# The matcher should accept one argument (Node),returns a bool.
func find_first_matched_nodes(root_node: Node, matcher: Callable) -> Array[Node]:
var result: Array[Node] = []
for node: Node in root_node.get_children():
var matches: bool = matcher.call(node)
if matches == true:
result.append(node)
continue
else:
var matched_nodes := find_first_matched_nodes(node, matcher)
result.append_array(matched_nodes)
return result
func _import(gltf_path: String, save_path, options, platform_variants, gen_files):
# Init.
#print("Source File: ", gltf_path)
#print("Save Path: ", save_path)
var root_node: Node
var meshLib: MeshLibrary = MeshLibrary.new()
var file = FileAccess.open(gltf_path, FileAccess.READ)
if file == null:
print("Error: File Not Found!")
return ERR_PARSE_ERROR
# load the GLTF file, init as Node.
var gltf_document_load := GLTFDocument.new()
var gltf_state_load := GLTFState.new()
var error := gltf_document_load.append_from_file(gltf_path, gltf_state_load)
if error == OK:
root_node = gltf_document_load.generate_scene(gltf_state_load)
else:
print("Error: %s " % error_string(error))
return error
# Get all MeshInstance3D nodes.
var mesh_nodes := find_first_matched_nodes(root_node, _is_ImporterMeshInstance3D)
# Add all meshes into MeshLibrary.
var i := 0
for mesh_node: ImporterMeshInstance3D in mesh_nodes:
var mesh: ArrayMesh = mesh_node.mesh.get_mesh() # Gets the mesh
meshLib.create_item(i)
meshLib.set_item_mesh(i, mesh)
meshLib.set_item_name(i, mesh_node.name)
# Spencer: Referencing https://github.com/Zincles/godot_gltf2meshlib/pull/1/files
var shape := mesh.create_trimesh_shape()
meshLib.set_item_shapes(i, [shape])
# Spencer: Another change (slightly hacky)
for mat_i in range(mesh.get_surface_count()):
var path := gltf_path + "/../" + mesh.surface_get_name(mat_i) + ".tres"
if ResourceLoader.exists(path):
var mat: Material = load(path)
mesh.surface_set_material(mat_i, mat)
else:
print("No material found at path: " + path)
print("Using built-in material instead")
var preview: Array[Texture2D] = EditorInterface.make_mesh_previews([mesh], 64)
meshLib.set_item_preview(i, preview[0])
i += 1
# Save
root_node.queue_free()
var filename = save_path + "." + _get_save_extension()
return ResourceSaver.save(meshLib, filename)
#endregion

View File

@ -0,0 +1,7 @@
[plugin]
name="gltf2meshlib"
description="A plugin that allows you to import gltf/glb as MeshLibrary, without taking a lot of manual steps."
author="Zincles"
version="0.1"
script="gltf2meshlib.gd"

BIN
blends/level_mesh_library.blend (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,10 +1,11 @@
[gd_scene load_steps=8 format=3 uid="uid://b00brfkibo5cj"]
[gd_scene load_steps=9 format=3 uid="uid://b00brfkibo5cj"]
[ext_resource type="PackedScene" uid="uid://bq654gwim6col" path="res://level/level.glb" id="1_s37in"]
[ext_resource type="Environment" uid="uid://covjrwmk4rplw" path="res://level/world_environment.tres" id="2_ptkl6"]
[ext_resource type="Script" path="res://level/level.gd" id="2_s1bx6"]
[ext_resource type="Script" path="res://addons/smoother/smoother.gd" id="5_2tyle"]
[ext_resource type="Script" path="res://level/PlayerSpawner.gd" id="6_7ww0m"]
[ext_resource type="MeshLibrary" uid="uid://cgh6y5j8wgi36" path="res://level/mesh_library/level_mesh_library.glb" id="6_d34iv"]
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ujmev"]
margin = 2.067
@ -42,3 +43,9 @@ script = ExtResource("6_7ww0m")
[node name="Smoother" type="Node" parent="." index="5"]
script = ExtResource("5_2tyle")
[node name="GridMap" type="GridMap" parent="." index="6"]
mesh_library = ExtResource("6_d34iv")
data = {
"cells": PackedInt32Array(65533, 65533, 1, 0, 65533, 0, 4, 65532, 0, 4, 65533, 0, 5, 65533, 0, 6, 65534, 0, 6, 65533, 0, 5, 65532, 0, 65535, 65531, 0, 0, 65530, 0, 1, 65530, 0, 4, 65528, 0, 3, 65528, 0, 65534, 65528, 0, 2, 65533, 0, 2, 2, 1, 7, 4, 0, 7, 3, 0, 7, 2, 0, 7, 1, 0, 7, 0, 0, 7, 65535, 0, 65533, 6, 0, 65534, 6, 0, 65535, 6, 0, 0, 6, 0, 1, 6, 0, 4, 9, 0, 4, 8, 0, 4, 7, 0, 4, 6, 0, 3, 7, 1, 8, 6, 1)
}

View File

@ -0,0 +1,7 @@
shader_type spatial;
uniform vec3 color : source_color;
void fragment() {
ALBEDO = color;
}

View File

@ -0,0 +1,8 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://bf3jwbci2dp72"]
[ext_resource type="Shader" path="res://level/mesh_library/Cube.gdshader" id="1_mi50m"]
[resource]
render_priority = 0
shader = ExtResource("1_mi50m")
shader_parameter/color = Color(0.2079, 0.531417, 0.353382, 1)

View File

@ -0,0 +1,7 @@
shader_type spatial;
uniform vec3 color : source_color;
void fragment() {
ALBEDO = color;
}

View File

@ -0,0 +1,8 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://cd67s24dcpqid"]
[ext_resource type="Shader" path="res://level/mesh_library/TallCube.gdshader" id="1_3trds"]
[resource]
render_priority = 0
shader = ExtResource("1_3trds")
shader_parameter/color = Color(1, 0.734185, 0.691036, 1)

BIN
level/mesh_library/level_mesh_library.glb (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,14 @@
[remap]
importer="zincles.gltf2meshlib"
type="MeshLibrary"
uid="uid://cgh6y5j8wgi36"
path="res://.godot/imported/level_mesh_library.glb-a98c6f38a714c03818db0f0b044793d1.meshlib"
[deps]
source_file="res://level/mesh_library/level_mesh_library.glb"
dest_files=["res://.godot/imported/level_mesh_library.glb-a98c6f38a714c03818db0f0b044793d1.meshlib"]
[params]

View File

@ -36,6 +36,11 @@ config/icon="res://icon.svg"
[autoload]
MultiplayerEvents="*res://server/MultiplayerEvents.gd"
FmodManager="*res://addons/fmod/FmodManager.gd"
[editor_plugins]
enabled=PackedStringArray("res://addons/fmod/plugin.cfg", "res://addons/godot_gltf2meshlib-6391ec247cc04f5fe89243b24fad68bc2ed2a96b/addons/gltf2meshlib/plugin.cfg")
[input]

8
tests/foo.tscn Normal file
View File

@ -0,0 +1,8 @@
[gd_scene load_steps=2 format=3 uid="uid://3ksclx7iiepo"]
[sub_resource type="MeshLibrary" id="MeshLibrary_8y7oa"]
[node name="Foo" type="Node3D"]
[node name="GridMap" type="GridMap" parent="."]
mesh_library = SubResource("MeshLibrary_8y7oa")