Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ addons/WAT/

# Godot-specific ignores
.import/
.godot/
export.cfg
export_presets.cfg

Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Kasper Arnklit Frandsen
Copyright (c) 2023 Kasper Arnklit Frandsen and Contributers

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
# Shell Fur Add-on for Godot Engine

[![Shell Fur Add-on for Godot v0.1.0 Released - Feature Overview](https://user-images.githubusercontent.com/4955051/97077434-8b0f7800-15db-11eb-98eb-7cecf1648304.png)](https://youtu.be/7EUjxwGTPAI "Shell Fur Add-on for Godot v0.1.0 Released - Feature Overview")
[![Shell Fur Add-on for Godot v0.3.0 Released - Feature Overview](https://user-images.githubusercontent.com/4955051/97077434-8b0f7800-15db-11eb-98eb-7cecf1648304.png)](https://youtu.be/7EUjxwGTPAI "Shell Fur Add-on for Godot v0.3.0 Released - Feature Overview")

Add-on that adds a fur node to Godot 3.4. Demo project available [here.](https://github.com/Arnklit/ShellFurGodotDemo)
Add-on that adds a fur node to Godot 4.1.
Migrated from Arnklit's Godot 3.4 version found [here.](https://github.com/Arnklit/ShellFurGodot)

[Discord Server](https://discord.gg/mjGvWwQwv2)

[Patreon](https://www.patreon.com/arnklit)

Installation
-----------
ShellFur is available on the Godot Asset Library, so the easiest way to install it into your project is directly inside Godot. Simply go to the AssetLib screen and search for "Fur" and the add-on should appear. Select it and press Download -> Install.

Alternatively you can press the green **Code** button at the top of this page and select **Download ZIP**, unzip the file and place the "shell_fur" folder in your project like so "addons/shell_fur*.
The Godot 4.1 version is not available on the Godot Asset Library, but you can press the green **Code** button at the top of this page and select **Download ZIP**, unzip the file and place the "shell_fur" folder in your project like so "addons/shell_fur*.

Once the files are in your project, you need to activate the add-on from the *Project -> Project Settings... -> Plugins* menu.

Expand Down
27 changes: 0 additions & 27 deletions addons/shell_fur/editor_property.gd

This file was deleted.

45 changes: 24 additions & 21 deletions addons/shell_fur/fur_helper_methods.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@

# Static functions used for generation of fur shells

static func generate_mmi(layers : int, mmi : MultiMeshInstance, mesh : Mesh, material : Material, blendshape_index : int, cast_shadow : bool) -> void:
static func generate_mmi(layers : int, mmi : MultiMeshInstance3D, mesh : Mesh, material : Material, blendshape_index : int, cast_shadow : bool) -> void:
var mdt = MeshDataTool.new()

if mmi.multimesh == null:
mmi.multimesh = MultiMesh.new()
mmi.multimesh.transform_format = MultiMesh.TRANSFORM_3D
mmi.multimesh.color_format = MultiMesh.COLOR_FLOAT
mmi.multimesh.custom_data_format = MultiMesh.CUSTOM_DATA_NONE
mmi.multimesh.use_colors = true

var new_mesh : Mesh = mesh.duplicate(true) as Mesh

Expand All @@ -26,7 +25,7 @@ static func generate_mmi(layers : int, mmi : MultiMeshInstance, mesh : Mesh, mat
mmi.multimesh.mesh.surface_set_material(surface, material)

for i in layers:
mmi.multimesh.set_instance_transform(i, Transform(Basis(), Vector3()))
mmi.multimesh.set_instance_transform(i, Transform3D(Basis(), Vector3()))
var grey = float(i) / float(layers)
mmi.multimesh.set_instance_color(i, Color(1.0, 1.0, 1.0, grey))

Expand All @@ -37,8 +36,8 @@ static func generate_mmi(layers : int, mmi : MultiMeshInstance, mesh : Mesh, mat
# the differences / extrusion vector as vertex colors to be used by the shader
static func _blendshape_to_vertex_color(mesh: Mesh, material : Material, blendshape_index: int) -> Mesh:
var mdt = MeshDataTool.new()
var base_mesh_array : PoolVector3Array
var fur_blend_shape_mesh_array : PoolVector3Array
var base_mesh_array : PackedVector3Array
var fur_blend_shape_mesh_array : PackedVector3Array

for m in mesh.get_surface_count():
base_mesh_array += mesh.surface_get_arrays(m)[0]
Expand Down Expand Up @@ -69,12 +68,12 @@ static func _blendshape_to_vertex_color(mesh: Mesh, material : Material, blendsh
var newz = _vertex_diff_to_vertex_color_value(compare_array[i].z, longest_diff_length)
compare_array_adjusted.append( Vector3(newx, newy, newz))

material.set_shader_param("i_blend_shape_multiplier", longest_diff_length)
material.set_shader_parameter("i_blend_shape_multiplier", longest_diff_length)

mdt.create_from_surface(_multiple_surfaces_to_single(mesh), 0)
for i in range(mdt.get_vertex_count()):
mdt.set_vertex_color(i, Color(compare_array_adjusted[i].x, compare_array_adjusted[i].y, compare_array_adjusted[i].z))
var new_mesh = Mesh.new()
var new_mesh = ArrayMesh.new()
mdt.commit_to_surface(new_mesh)

return new_mesh
Expand All @@ -85,13 +84,13 @@ static func _blendshape_to_vertex_color(mesh: Mesh, material : Material, blendsh
# regardless of whether a custom extrusion vector is set.
static func _normals_to_vertex_color(mesh: Mesh, material : Material) -> Mesh:
var mdt = MeshDataTool.new()
material.set_shader_param("i_blend_shape_multiplier", 1.0)
material.set_shader_parameter("i_blend_shape_multiplier", 1.0)

mdt.create_from_surface(_multiple_surfaces_to_single(mesh), 0)
for i in range(mdt.get_vertex_count()):
var normal_scaled = mdt.get_vertex_normal(i) * 0.5 + Vector3(0.5, 0.5, 0.5)
mdt.set_vertex_color(i, Color(normal_scaled.x, normal_scaled.y, normal_scaled.z))
var new_mesh = Mesh.new()
var new_mesh = ArrayMesh.new()
mdt.commit_to_surface(new_mesh)

return new_mesh
Expand All @@ -101,7 +100,11 @@ static func reorder_params(unordered_params : Array) -> Array:
var ordered = []

for param in unordered_params:
if param.hint_string != "Texture":
# In Godot 4 hints from shaders are Texture2D while the Editor hint is just Texture. We rename it here to be the same.
if param.hint_string == "Texture2D":
param.hint_string = "Texture2D"

if param.hint_string != "Texture2D":
ordered.append(param)
else:
#find the last index in ordered with the same
Expand All @@ -117,7 +120,7 @@ static func reorder_params(unordered_params : Array) -> Array:
static func last_prefix_occurence(array : Array, search : String) -> int:

var inverted_array = array.duplicate(true)
inverted_array.invert()
inverted_array.reverse()

for i in array.size():
var prefix = inverted_array[i].name.rsplit("_")[0]
Expand All @@ -129,10 +132,10 @@ static func last_prefix_occurence(array : Array, search : String) -> int:

static func _multiple_surfaces_to_single(mesh : Mesh) -> Mesh:
var st := SurfaceTool.new()
var merging_mesh = Mesh.new()
var merging_mesh = ArrayMesh.new()

for surface in mesh.get_surface_count():
st.append_from(mesh, surface, Transform.IDENTITY)
st.append_from(mesh, surface, Transform3D.IDENTITY)
merging_mesh = st.commit()

return merging_mesh
Expand All @@ -142,7 +145,7 @@ static func _vertex_diff_to_vertex_color_value(value : float, factor : float) ->
return (value / factor) * 0.5 + 0.5


static func generate_mesh_shells(shell_fur_object : Spatial, parent_object : Spatial, layers : int, material : Material, blendshape_index : int):
static func generate_mesh_shells(shell_fur_object : Node3D, parent_object : Node3D, layers : int, material : Material, blendshape_index : int):
var mdt = MeshDataTool.new()
var copy_mesh : Mesh = parent_object.mesh.duplicate(true)

Expand All @@ -154,7 +157,7 @@ static func generate_mesh_shells(shell_fur_object : Spatial, parent_object : Spa
var merged_mesh = _multiple_surfaces_to_single(copy_mesh)

for layer in layers:
var new_object = MeshInstance.new()
var new_object = MeshInstance3D.new()
new_object.name = "fur_layer_" + str(layer)
shell_fur_object.add_child(new_object)
# Uncomment to debug whether shells are getting created
Expand All @@ -164,27 +167,27 @@ static func generate_mesh_shells(shell_fur_object : Spatial, parent_object : Spa
var c = mdt.get_vertex_color(i)
c.a = float(layer) / float(layers)
mdt.set_vertex_color(i, c)
var new_mesh := Mesh.new()
var new_mesh := ArrayMesh.new()
mdt.commit_to_surface(new_mesh)
new_object.mesh = new_mesh


static func generate_combined(shell_fur_object : Spatial, parent_object : Spatial, material : Material, cast_shadow : bool) -> Spatial:
static func generate_combined(shell_fur_object : Node3D, parent_object : Node3D, material : Material, cast_shadow : bool) -> Node3D:
var st = SurfaceTool.new()

for child in shell_fur_object.get_children():
st.append_from(child.mesh, 0, Transform.IDENTITY)
st.append_from(child.mesh, 0, Transform3D.IDENTITY)
child.free()

st.index()
var combined_obj := MeshInstance.new()
var combined_obj := MeshInstance3D.new()

combined_obj.name = "CombinedFurMesh"
combined_obj.mesh = st.commit()
shell_fur_object.add_child(combined_obj)
# Uncomment to check whether the object is getting created
#combined_obj.set_owner(shell_fur_object.get_tree().get_edited_scene_root())
combined_obj.set_surface_material(0, material)
combined_obj.set_surface_override_material(0, material)
combined_obj.set_skin(parent_object.get_skin())
combined_obj.set_skeleton_path("../../..")
combined_obj.cast_shadow = 1 if cast_shadow else 0
Expand Down
32 changes: 17 additions & 15 deletions addons/shell_fur/fur_node_icon.svg.import
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
[remap]

importer="texture"
type="StreamTexture"
path="res://.import/fur_node_icon.svg-e36258f5e2232b9188ca7ac73c8b5d1a.stex"
type="CompressedTexture2D"
uid="uid://bduiasrdrkl8m"
path="res://.godot/imported/fur_node_icon.svg-e36258f5e2232b9188ca7ac73c8b5d1a.ctex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://addons/shell_fur/fur_node_icon.svg"
dest_files=[ "res://.import/fur_node_icon.svg-e36258f5e2232b9188ca7ac73c8b5d1a.stex" ]
dest_files=["res://.godot/imported/fur_node_icon.svg-e36258f5e2232b9188ca7ac73c8b5d1a.ctex"]

[params]

compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/hdr_compression=1
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
18 changes: 0 additions & 18 deletions addons/shell_fur/gui/gradient_inspector.gd

This file was deleted.

44 changes: 0 additions & 44 deletions addons/shell_fur/gui/gradient_inspector.tscn

This file was deleted.

18 changes: 0 additions & 18 deletions addons/shell_fur/inspector_plugin.gd

This file was deleted.

Loading