Restore authored hand net

This commit is contained in:
Alexander Sellite 2026-08-25 17:14:22 -04:00
parent 7ae20789a9
commit 737d1cf2e0
10 changed files with 284 additions and 66 deletions

Binary file not shown.

View file

@ -0,0 +1,45 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://dsa6yss1sxfcy"
path="res://.godot/imported/net.glb-cbbc53905aec6a50c4a3322ca7a93b1e.scn"
[deps]
source_file="res://art/exported/items/equipment/net.glb"
dest_files=["res://.godot/imported/net.glb-cbbc53905aec6a50c4a3322ca7a93b1e.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
gltf/texture_map_mode=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

View file

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dprm50tbiulog"
path="res://.godot/imported/net_Material.png-f4c4b0400561bc2751fe719b6b1a1e1a.ctex"
metadata={
"vram_texture": false
}
generator_parameters={
"md5": "ef2c2ae657c9460c90eb808ba5217f39"
}
[deps]
source_file="res://art/exported/items/equipment/net_Material.png"
dest_files=["res://.godot/imported/net_Material.png-f4c4b0400561bc2751fe719b6b1a1e1a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View file

@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://seq5b31mwcqr"
path="res://.godot/imported/net_Plane Base Color.png-3875ae3dd186ddf319c55aabb13e663f.ctex"
metadata={
"vram_texture": false
}
generator_parameters={
"md5": "a6001c381d4c8e16bd2d64ea74ccff82"
}
[deps]
source_file="res://art/exported/items/equipment/net_Plane Base Color.png"
dest_files=["res://.godot/imported/net_Plane Base Color.png-3875ae3dd186ddf319c55aabb13e663f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

View file

@ -1,7 +1,88 @@
extends "res://player/tool_socket_attachment.gd" extends "res://player/tool_socket_attachment.gd"
@onready var _impact_marker: Marker3D = %ImpactMarker const TextureSamplingPolicyScript := preload(
"res://main/texture_sampling_policy.gd"
)
const SPRING_ROOT_BONE: StringName = &"net_mid"
const SPRING_END_BONE: StringName = &"net_tip"
const IMPACT_BONE: StringName = &"net_rim"
@export_range(0.0, 10.0, 0.05) var spring_stiffness: float = 1.8
@export_range(0.0, 1.0, 0.01) var spring_drag: float = 0.68
@export_range(0.0, 10.0, 0.05) var spring_gravity: float = 0.3
@export_range(0.01, 0.5, 0.01) var spring_end_length: float = 0.1
@onready var _catching_net: Node3D = %CatchingNet
@onready var _net_model: Node3D = %NetModel
var _spring: SpringBoneSimulator3D
var _spring_was_visible: bool = false
var _net_skeleton: Skeleton3D
func _ready() -> void:
super._ready()
TextureSamplingPolicyScript.enforce_subtree(_net_model)
_configure_spring()
_sync_spring_activity()
func _process(_delta: float) -> void:
_sync_spring_activity()
func _configure_spring() -> void:
_net_skeleton = _net_model.find_child(
"Skeleton3D", true, false
) as Skeleton3D
if _net_skeleton == null:
push_error("Imported net model is missing its Skeleton3D.")
return
if _net_skeleton.find_bone(SPRING_ROOT_BONE) < 0:
push_error("Imported net model is missing bone %s." % SPRING_ROOT_BONE)
return
if _net_skeleton.find_bone(SPRING_END_BONE) < 0:
push_error("Imported net model is missing bone %s." % SPRING_END_BONE)
return
if _net_skeleton.find_bone(IMPACT_BONE) < 0:
push_error("Imported net model is missing bone %s." % IMPACT_BONE)
return
_spring = SpringBoneSimulator3D.new()
_spring.name = "NetSpring"
_spring.set_setting_count(1)
_spring.set_root_bone_name(0, SPRING_ROOT_BONE)
_spring.set_end_bone_name(0, SPRING_END_BONE)
_spring.set_extend_end_bone(0, true)
_spring.set_end_bone_direction(
0, SkeletonModifier3D.BONE_DIRECTION_FROM_PARENT
)
_spring.set_end_bone_length(0, spring_end_length)
_spring.set_stiffness(0, spring_stiffness)
_spring.set_drag(0, spring_drag)
_spring.set_gravity(0, spring_gravity)
_spring.set_gravity_direction(0, Vector3.DOWN)
_net_skeleton.add_child(_spring)
func get_impact_world_position() -> Vector3: func get_impact_world_position() -> Vector3:
return _impact_marker.global_position if _net_skeleton == null:
return _catching_net.global_position
var impact_bone_index := _net_skeleton.find_bone(IMPACT_BONE)
if impact_bone_index < 0:
return _catching_net.global_position
return _net_skeleton.global_transform * (
_net_skeleton.get_bone_global_pose(impact_bone_index).origin
)
func _sync_spring_activity() -> void:
if _spring == null:
return
var is_visible := _catching_net.is_visible_in_tree()
if is_visible and not _spring_was_visible:
_spring.active = true
_spring.reset()
elif not is_visible:
_spring.active = false
_spring_was_visible = is_visible

View file

@ -1,42 +1,7 @@
[gd_scene load_steps=8 format=3] [gd_scene load_steps=3 format=3]
[ext_resource type="Script" path="res://player/net_attachment.gd" id="1_script"] [ext_resource type="Script" path="res://player/net_attachment.gd" id="1_script"]
[ext_resource type="PackedScene" path="res://art/exported/items/equipment/net.glb" id="2_model"]
[sub_resource type="StandardMaterial3D" id="HandleMaterial"]
albedo_color = Color(0.25, 0.13, 0.055, 1)
roughness = 0.9
[sub_resource type="CylinderMesh" id="HandleMesh"]
material = SubResource("HandleMaterial")
top_radius = 0.025
bottom_radius = 0.035
height = 1.25
[sub_resource type="StandardMaterial3D" id="HoopMaterial"]
albedo_color = Color(0.34, 0.39, 0.4, 1)
metallic = 0.25
roughness = 0.65
[sub_resource type="TorusMesh" id="HoopMesh"]
material = SubResource("HoopMaterial")
inner_radius = 0.24
outer_radius = 0.29
rings = 12
ring_segments = 18
[sub_resource type="StandardMaterial3D" id="NetMaterial"]
transparency = 1
albedo_color = Color(0.65, 0.78, 0.75, 0.42)
shading_mode = 0
cull_mode = 2
[sub_resource type="CylinderMesh" id="NetMesh"]
material = SubResource("NetMaterial")
top_radius = 0.24
bottom_radius = 0.08
height = 0.34
radial_segments = 12
rings = 1
[node name="NetAttachment" type="BoneAttachment3D"] [node name="NetAttachment" type="BoneAttachment3D"]
bone_name = "rod_socket" bone_name = "rod_socket"
@ -47,18 +12,9 @@ aligned_mount_path = NodePath("CatchingNet")
unique_name_in_owner = true unique_name_in_owner = true
visible = false visible = false
[node name="Handle" type="MeshInstance3D" parent="CatchingNet"] [node name="ModelMount" type="Node3D" parent="CatchingNet"]
position = Vector3(0, 0.55, 0) position = Vector3(-0.000217, -0.098636, -0.020218)
mesh = SubResource("HandleMesh") rotation = Vector3(0, 3.1415927, 0)
[node name="Hoop" type="MeshInstance3D" parent="CatchingNet"] [node name="NetModel" parent="CatchingNet/ModelMount" unique_id=1627767240 instance=ExtResource("2_model")]
position = Vector3(0, 1.17, 0)
mesh = SubResource("HoopMesh")
[node name="Bag" type="MeshInstance3D" parent="CatchingNet"]
position = Vector3(0, 1, 0)
mesh = SubResource("NetMesh")
[node name="ImpactMarker" type="Marker3D" parent="CatchingNet"]
unique_name_in_owner = true unique_name_in_owner = true
position = Vector3(0, 1.17, 0)

View file

@ -57,23 +57,73 @@ func _run() -> void:
"Net rear face did not follow the socket direction guide.", "Net rear face did not follow the socket direction guide.",
) )
var handle := catching_net.get_node_or_null("Handle") as MeshInstance3D var model := catching_net.get_node_or_null("ModelMount/NetModel") as Node3D
var hoop := catching_net.get_node_or_null("Hoop") as MeshInstance3D _check(model != null, "Imported net model is missing.")
var bag := catching_net.get_node_or_null("Bag") as MeshInstance3D if model == null:
var impact_marker := ( _finish(host_skeleton)
catching_net.get_node_or_null("ImpactMarker") as Marker3D return
var skeleton := model.find_child("Skeleton3D", true, false) as Skeleton3D
_check(skeleton != null, "Imported net Skeleton3D is missing.")
if skeleton == null:
_finish(host_skeleton)
return
_check(
skeleton.find_bone("net_root") >= 0,
"Imported net_root bone is missing.",
) )
_check(handle != null and handle.mesh != null, "Placeholder handle is missing.") _check(
_check(hoop != null and hoop.mesh != null, "Placeholder hoop is missing.") skeleton.find_bone("net_rim") >= 0,
_check(bag != null and bag.mesh != null, "Placeholder net bag is missing.") "Imported net_rim bone is missing.",
_check(impact_marker != null, "Net impact marker is missing.") )
if impact_marker != null: _check(
skeleton.find_bone("net_mid") >= 0,
"Imported net_mid bone is missing.",
)
_check(
skeleton.find_bone("net_tip") >= 0,
"Imported net_tip bone is missing.",
)
var spring := skeleton.get_node_or_null("NetSpring") as SpringBoneSimulator3D
_check(spring != null, "Net spring simulator was not created.")
if spring != null:
_check(spring.get_setting_count() == 1, "Net spring settings changed.")
_check( _check(
attachment.get_impact_world_position().is_equal_approx( spring.get_root_bone_name(0) == &"net_mid",
impact_marker.global_position "Net spring root must remain net_mid.",
),
"Net impact position moved away from its marker.",
) )
_check(
spring.get_end_bone_name(0) == &"net_tip",
"Net spring end must remain net_tip.",
)
_check(not spring.active, "Hidden net spring must be suspended.")
catching_net.visible = true
await process_frame
await process_frame
_check(spring.active, "Visible net spring must be active.")
_check(spring.get_joint_count(0) == 2, "Net spring chain is incomplete.")
_check(
not attachment.get_impact_world_position().is_equal_approx(
catching_net.global_position
),
"Net impact position did not follow the authored rim bone.",
)
catching_net.visible = false
await process_frame
_check(not spring.active, "Hidden net spring did not suspend.")
for child: Node in model.find_children("*", "MeshInstance3D", true, false):
var mesh_instance := child as MeshInstance3D
if mesh_instance.mesh == null:
continue
for surface_index: int in mesh_instance.mesh.get_surface_count():
var material := mesh_instance.mesh.surface_get_material(surface_index)
if material is BaseMaterial3D:
_check(
(material as BaseMaterial3D).texture_filter
== BaseMaterial3D.TEXTURE_FILTER_NEAREST,
"Net material does not use nearest texture sampling.",
)
var rod_attachment := ( var rod_attachment := (
FishingRodAttachmentScene.instantiate() as BoneAttachment3D FishingRodAttachmentScene.instantiate() as BoneAttachment3D