init
This commit is contained in:
17
addons/godot-xr-tools/hands/About.md
Normal file
17
addons/godot-xr-tools/hands/About.md
Normal file
@@ -0,0 +1,17 @@
|
||||
The Hand Mesh was made using the Makehuman Community Edition
|
||||
It was slightly modified inside Blender 3D and textured inside Substance Painter
|
||||
|
||||
If there should be concerns regarding License issues
|
||||
https://github.com/makehumancommunity/makehuman/blob/master/LICENSE.md
|
||||
|
||||
under point D of the makehuman communtiy edition license
|
||||
https://github.com/makehumancommunity/makehuman/blob/master/LICENSE.md#d-concerning-the-output-from-makehuman
|
||||
As the assets have been released under CC0, there is no limitation on what you can do with this combined output.
|
||||
The MakeHuman project makes no claim whatsoever over output such as:
|
||||
|
||||
Exports to files (FBX, OBJ, DAE, MHX2...)
|
||||
Exports via direct integration (import via MPFB)
|
||||
Graphical data generated via scripting or plugins
|
||||
Renderings
|
||||
Screenshots
|
||||
Saved model files
|
||||
126
addons/godot-xr-tools/hands/License.md
Normal file
126
addons/godot-xr-tools/hands/License.md
Normal file
@@ -0,0 +1,126 @@
|
||||
To the extent possible under law, DigitalN8m4r3 aka Miodrag Sejic
|
||||
has waived all copyright and related or neighboring rights to Hand Models for the Godot XR Tools.
|
||||
This work is published from: Austria.
|
||||
Date: 7th November 2022
|
||||
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
||||
@@ -0,0 +1,81 @@
|
||||
[gd_scene load_steps=37 format=3 uid="uid://the6y7swe6j0"]
|
||||
|
||||
[ext_resource type="Animation" uid="uid://dgfeikrugfewi" path="res://addons/godot-xr-tools/hands/animations/left/Cup.res" id="1_7svyl"]
|
||||
[ext_resource type="Animation" uid="uid://dlxa6f6hwurka" path="res://addons/godot-xr-tools/hands/animations/left/Default pose.res" id="2_ykhfd"]
|
||||
[ext_resource type="Animation" uid="uid://dqa0h82y3qn1t" path="res://addons/godot-xr-tools/hands/animations/left/Grip 1.res" id="3_y80ds"]
|
||||
[ext_resource type="Animation" uid="uid://di384xtde8ydf" path="res://addons/godot-xr-tools/hands/animations/left/Grip 2.res" id="4_1nbr8"]
|
||||
[ext_resource type="Animation" uid="uid://dd67rufxwj2u" path="res://addons/godot-xr-tools/hands/animations/left/Grip 3.res" id="5_28lp1"]
|
||||
[ext_resource type="Animation" uid="uid://db62hs5s4n2b3" path="res://addons/godot-xr-tools/hands/animations/left/Grip 4.res" id="6_uj648"]
|
||||
[ext_resource type="Animation" uid="uid://bediglpx0rj7i" path="res://addons/godot-xr-tools/hands/animations/left/Grip 5.res" id="7_yxjeh"]
|
||||
[ext_resource type="Animation" uid="uid://nq3xh1olqipq" path="res://addons/godot-xr-tools/hands/animations/left/Grip Shaft.res" id="8_i0ro5"]
|
||||
[ext_resource type="Animation" uid="uid://plad1r85f7ws" path="res://addons/godot-xr-tools/hands/animations/left/Grip.res" id="9_811qe"]
|
||||
[ext_resource type="Animation" uid="uid://bi1l6lre2w2lp" path="res://addons/godot-xr-tools/hands/animations/left/Hold.res" id="10_o5u3q"]
|
||||
[ext_resource type="Animation" uid="uid://c3e6h0rv2uw2d" path="res://addons/godot-xr-tools/hands/animations/left/Horns.res" id="11_i2b8g"]
|
||||
[ext_resource type="Animation" uid="uid://dfekure1r6q13" path="res://addons/godot-xr-tools/hands/animations/left/Metal.res" id="12_yoig6"]
|
||||
[ext_resource type="Animation" uid="uid://b0rhk4r0r0t32" path="res://addons/godot-xr-tools/hands/animations/left/Middle.res" id="13_kvhwh"]
|
||||
[ext_resource type="Animation" uid="uid://f5k0gh4qnmv5" path="res://addons/godot-xr-tools/hands/animations/left/OK.res" id="14_ofab3"]
|
||||
[ext_resource type="Animation" uid="uid://1nlkfvitq7ku" path="res://addons/godot-xr-tools/hands/animations/left/Peace.res" id="15_a4q3y"]
|
||||
[ext_resource type="Animation" uid="uid://dhjb0e334tfwl" path="res://addons/godot-xr-tools/hands/animations/left/Pinch Flat.res" id="16_ixe2d"]
|
||||
[ext_resource type="Animation" uid="uid://dkjsnihi81b7p" path="res://addons/godot-xr-tools/hands/animations/left/Pinch Large.res" id="17_oifug"]
|
||||
[ext_resource type="Animation" uid="uid://bn0fdhe2jwq3h" path="res://addons/godot-xr-tools/hands/animations/left/Pinch Middle.res" id="18_2ic2e"]
|
||||
[ext_resource type="Animation" uid="uid://bo1b8w0s4ci81" path="res://addons/godot-xr-tools/hands/animations/left/Pinch Ring.res" id="19_4a8v4"]
|
||||
[ext_resource type="Animation" uid="uid://m5x2m8x3tcel" path="res://addons/godot-xr-tools/hands/animations/left/Pinch Tight.res" id="20_ugc01"]
|
||||
[ext_resource type="Animation" uid="uid://fi23m6i7orhw" path="res://addons/godot-xr-tools/hands/animations/left/Pinch Up.res" id="21_l3kgg"]
|
||||
[ext_resource type="Animation" uid="uid://c8qmcuyaltdnw" path="res://addons/godot-xr-tools/hands/animations/left/PingPong.res" id="22_j83er"]
|
||||
[ext_resource type="Animation" uid="uid://bqnoubqq7ogwu" path="res://addons/godot-xr-tools/hands/animations/left/Pinky.res" id="23_sm4sd"]
|
||||
[ext_resource type="Animation" uid="uid://ddbo6ioa282en" path="res://addons/godot-xr-tools/hands/animations/left/Pistol.res" id="24_r4kss"]
|
||||
[ext_resource type="Animation" uid="uid://brkptjihht3ae" path="res://addons/godot-xr-tools/hands/animations/left/Ring.res" id="25_2ncut"]
|
||||
[ext_resource type="Animation" uid="uid://cnng6xumhw7cx" path="res://addons/godot-xr-tools/hands/animations/left/Rounded.res" id="26_02lfv"]
|
||||
[ext_resource type="Animation" uid="uid://cevirj0eagdrq" path="res://addons/godot-xr-tools/hands/animations/left/Sign 1.res" id="27_o5si3"]
|
||||
[ext_resource type="Animation" uid="uid://cc6phxovf1ban" path="res://addons/godot-xr-tools/hands/animations/left/Sign 2.res" id="28_ble5k"]
|
||||
[ext_resource type="Animation" uid="uid://ohthjp8qbcc4" path="res://addons/godot-xr-tools/hands/animations/left/Sign 3.res" id="29_twq1x"]
|
||||
[ext_resource type="Animation" uid="uid://dmx42g64577g5" path="res://addons/godot-xr-tools/hands/animations/left/Sign 4.res" id="30_eyeuv"]
|
||||
[ext_resource type="Animation" uid="uid://dhsoxntrktx0p" path="res://addons/godot-xr-tools/hands/animations/left/Sign 5.res" id="31_50jrs"]
|
||||
[ext_resource type="Animation" uid="uid://c0u2a3yc2vhg8" path="res://addons/godot-xr-tools/hands/animations/left/Sign_Point.res" id="32_7v122"]
|
||||
[ext_resource type="Animation" uid="uid://4g211my0hoiw" path="res://addons/godot-xr-tools/hands/animations/left/Straight.res" id="33_m3lif"]
|
||||
[ext_resource type="Animation" uid="uid://d06l7hygl4qt3" path="res://addons/godot-xr-tools/hands/animations/left/Surfer.res" id="34_b3p10"]
|
||||
[ext_resource type="Animation" uid="uid://bxei4oebd4hu3" path="res://addons/godot-xr-tools/hands/animations/left/Thumb.res" id="35_huikq"]
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_kw48d"]
|
||||
_data = {
|
||||
&"Cup": ExtResource("1_7svyl"),
|
||||
&"Default pose": ExtResource("2_ykhfd"),
|
||||
&"Grip": ExtResource("9_811qe"),
|
||||
&"Grip 1": ExtResource("3_y80ds"),
|
||||
&"Grip 2": ExtResource("4_1nbr8"),
|
||||
&"Grip 3": ExtResource("5_28lp1"),
|
||||
&"Grip 4": ExtResource("6_uj648"),
|
||||
&"Grip 5": ExtResource("7_yxjeh"),
|
||||
&"Grip Shaft": ExtResource("8_i0ro5"),
|
||||
&"Hold": ExtResource("10_o5u3q"),
|
||||
&"Horns": ExtResource("11_i2b8g"),
|
||||
&"Metal": ExtResource("12_yoig6"),
|
||||
&"Middle": ExtResource("13_kvhwh"),
|
||||
&"OK": ExtResource("14_ofab3"),
|
||||
&"Peace": ExtResource("15_a4q3y"),
|
||||
&"Pinch Flat": ExtResource("16_ixe2d"),
|
||||
&"Pinch Large": ExtResource("17_oifug"),
|
||||
&"Pinch Middle": ExtResource("18_2ic2e"),
|
||||
&"Pinch Ring": ExtResource("19_4a8v4"),
|
||||
&"Pinch Tight": ExtResource("20_ugc01"),
|
||||
&"Pinch Up": ExtResource("21_l3kgg"),
|
||||
&"PingPong": ExtResource("22_j83er"),
|
||||
&"Pinky": ExtResource("23_sm4sd"),
|
||||
&"Pistol": ExtResource("24_r4kss"),
|
||||
&"Ring": ExtResource("25_2ncut"),
|
||||
&"Rounded": ExtResource("26_02lfv"),
|
||||
&"Sign 1": ExtResource("27_o5si3"),
|
||||
&"Sign 2": ExtResource("28_ble5k"),
|
||||
&"Sign 3": ExtResource("29_twq1x"),
|
||||
&"Sign 4": ExtResource("30_eyeuv"),
|
||||
&"Sign 5": ExtResource("31_50jrs"),
|
||||
&"Sign_Point": ExtResource("32_7v122"),
|
||||
&"Straight": ExtResource("33_m3lif"),
|
||||
&"Surfer": ExtResource("34_b3p10"),
|
||||
&"Thumb": ExtResource("35_huikq")
|
||||
}
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer"]
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_kw48d")
|
||||
}
|
||||
BIN
addons/godot-xr-tools/hands/animations/left/Cup.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Cup.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Default pose.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Default pose.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Grip 1.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Grip 1.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Grip 2.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Grip 2.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Grip 3.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Grip 3.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Grip 4.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Grip 4.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Grip 5.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Grip 5.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Grip Shaft.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Grip Shaft.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Grip.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Grip.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Hold.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Hold.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Horns.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Horns.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Metal.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Metal.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Middle.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Middle.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/OK.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/OK.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Peace.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Peace.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Flat.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Flat.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Large.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Large.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Middle.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Middle.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Ring.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Ring.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Tight.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Tight.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Up.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Pinch Up.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/PingPong.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/PingPong.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Pinky.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Pinky.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Pistol.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Pistol.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Ring.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Ring.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Rounded.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Rounded.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Sign 1.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Sign 1.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Sign 2.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Sign 2.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Sign 3.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Sign 3.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Sign 4.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Sign 4.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Sign 5.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Sign 5.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Sign_Point.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Sign_Point.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Straight.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Straight.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Surfer.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Surfer.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/left/Thumb.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/left/Thumb.res
Normal file
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
[gd_resource type="AnimationNodeBlendTree" load_steps=6 format=3 uid="uid://dl8yf7ipqotd1"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="1"]
|
||||
animation = &"Grip"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="2"]
|
||||
animation = &"Grip"
|
||||
|
||||
[sub_resource type="AnimationNodeBlend2" id="3"]
|
||||
filter_enabled = true
|
||||
filters = ["Armature/Skeleton3D:Little_Distal_L", "Armature/Skeleton3D:Little_Intermediate_L", "Armature/Skeleton3D:Little_Metacarpal_L", "Armature/Skeleton3D:Little_Proximal_L", "Armature/Skeleton3D:Middle_Distal_L", "Armature/Skeleton3D:Middle_Intermediate_L", "Armature/Skeleton3D:Middle_Metacarpal_L", "Armature/Skeleton3D:Middle_Proximal_L", "Armature/Skeleton3D:Ring_Distal_L", "Armature/Skeleton3D:Ring_Intermediate_L", "Armature/Skeleton3D:Ring_Metacarpal_L", "Armature/Skeleton3D:Ring_Proximal_L", "Armature/Skeleton3D:Thumb_Distal_L", "Armature/Skeleton3D:Thumb_Metacarpal_L", "Armature/Skeleton3D:Thumb_Proximal_L", "Armature/Skeleton:Little_Distal_L", "Armature/Skeleton:Little_Intermediate_L", "Armature/Skeleton:Little_Proximal_L", "Armature/Skeleton:Middle_Distal_L", "Armature/Skeleton:Middle_Intermediate_L", "Armature/Skeleton:Middle_Proximal_L", "Armature/Skeleton:Ring_Distal_L", "Armature/Skeleton:Ring_Intermediate_L", "Armature/Skeleton:Ring_Proximal_L", "Armature/Skeleton:Thumb_Distal_L", "Armature/Skeleton:Thumb_Proximal_L"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="4"]
|
||||
animation = &"Grip 5"
|
||||
|
||||
[sub_resource type="AnimationNodeBlend2" id="5"]
|
||||
filter_enabled = true
|
||||
filters = ["Armature/Skeleton3D:Index_Distal_L", "Armature/Skeleton3D:Index_Intermediate_L", "Armature/Skeleton3D:Index_Metacarpal_L", "Armature/Skeleton3D:Index_Proximal_L", "Armature/Skeleton:Index_Distal_L", "Armature/Skeleton:Index_Intermediate_L", "Armature/Skeleton:Index_Proximal_L"]
|
||||
|
||||
[resource]
|
||||
graph_offset = Vector2(-536, 11)
|
||||
nodes/ClosedHand1/node = SubResource("1")
|
||||
nodes/ClosedHand1/position = Vector2(-600, 300)
|
||||
nodes/ClosedHand2/node = SubResource("2")
|
||||
nodes/ClosedHand2/position = Vector2(-360, 300)
|
||||
nodes/Grip/node = SubResource("3")
|
||||
nodes/Grip/position = Vector2(0, 20)
|
||||
nodes/OpenHand/node = SubResource("4")
|
||||
nodes/OpenHand/position = Vector2(-600, 100)
|
||||
nodes/Trigger/node = SubResource("5")
|
||||
nodes/Trigger/position = Vector2(-360, 20)
|
||||
node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"]
|
||||
@@ -0,0 +1,81 @@
|
||||
[gd_scene load_steps=37 format=3 uid="uid://bxipj7hyjwy6f"]
|
||||
|
||||
[ext_resource type="Animation" uid="uid://do01jton6rk42" path="res://addons/godot-xr-tools/hands/animations/right/Cup.res" id="1_mq7eu"]
|
||||
[ext_resource type="Animation" uid="uid://ky28birj4su6" path="res://addons/godot-xr-tools/hands/animations/right/Default pose.res" id="2_kxlaj"]
|
||||
[ext_resource type="Animation" uid="uid://daqddcrbpam0c" path="res://addons/godot-xr-tools/hands/animations/right/Grip 1.res" id="3_5xubn"]
|
||||
[ext_resource type="Animation" uid="uid://r8hleealhrqt" path="res://addons/godot-xr-tools/hands/animations/right/Grip 2.res" id="4_y3ovo"]
|
||||
[ext_resource type="Animation" uid="uid://rs7vpclot07o" path="res://addons/godot-xr-tools/hands/animations/right/Grip 3.res" id="5_0d4pg"]
|
||||
[ext_resource type="Animation" uid="uid://d1xnpyc08njjx" path="res://addons/godot-xr-tools/hands/animations/right/Grip 4.res" id="6_nabm2"]
|
||||
[ext_resource type="Animation" uid="uid://s1vqcxyqcvea" path="res://addons/godot-xr-tools/hands/animations/right/Grip 5.res" id="7_gy2yb"]
|
||||
[ext_resource type="Animation" uid="uid://c8dghcftg1thx" path="res://addons/godot-xr-tools/hands/animations/right/Grip Shaft.res" id="8_ffwxq"]
|
||||
[ext_resource type="Animation" uid="uid://ccds2u22gbxn7" path="res://addons/godot-xr-tools/hands/animations/right/Grip.res" id="9_y16mo"]
|
||||
[ext_resource type="Animation" uid="uid://bv5tuc1kjv0k5" path="res://addons/godot-xr-tools/hands/animations/right/Hold.res" id="10_g8e21"]
|
||||
[ext_resource type="Animation" uid="uid://cdjfhqnr4n2mr" path="res://addons/godot-xr-tools/hands/animations/right/Horns.res" id="11_b3lks"]
|
||||
[ext_resource type="Animation" uid="uid://b1kqsodcr1til" path="res://addons/godot-xr-tools/hands/animations/right/Metal.res" id="12_p14fk"]
|
||||
[ext_resource type="Animation" uid="uid://cg6fsqb2iuuih" path="res://addons/godot-xr-tools/hands/animations/right/Middle.res" id="13_4i278"]
|
||||
[ext_resource type="Animation" uid="uid://c3isimdlxg54a" path="res://addons/godot-xr-tools/hands/animations/right/OK.res" id="14_qk7tg"]
|
||||
[ext_resource type="Animation" uid="uid://bxmc3vlfih764" path="res://addons/godot-xr-tools/hands/animations/right/Peace.res" id="15_ejppt"]
|
||||
[ext_resource type="Animation" uid="uid://dg4v7rqiaje2h" path="res://addons/godot-xr-tools/hands/animations/right/Pinch Flat.res" id="16_7cyln"]
|
||||
[ext_resource type="Animation" uid="uid://cuwwpxi44vwpm" path="res://addons/godot-xr-tools/hands/animations/right/Pinch Large.res" id="17_amtgc"]
|
||||
[ext_resource type="Animation" uid="uid://c6vghurk7t5yb" path="res://addons/godot-xr-tools/hands/animations/right/Pinch Middle.res" id="18_pnqcq"]
|
||||
[ext_resource type="Animation" uid="uid://mjotm5uukoo3" path="res://addons/godot-xr-tools/hands/animations/right/Pinch Ring.res" id="19_aeaff"]
|
||||
[ext_resource type="Animation" uid="uid://ca21ej1p3g2yt" path="res://addons/godot-xr-tools/hands/animations/right/Pinch Tight.res" id="20_mghnf"]
|
||||
[ext_resource type="Animation" uid="uid://cseojxi8rrqc" path="res://addons/godot-xr-tools/hands/animations/right/Pinch Up.res" id="21_1v6tw"]
|
||||
[ext_resource type="Animation" uid="uid://c8hn123uon74u" path="res://addons/godot-xr-tools/hands/animations/right/PingPong.res" id="22_ueac0"]
|
||||
[ext_resource type="Animation" uid="uid://b6ra3rqia1gvb" path="res://addons/godot-xr-tools/hands/animations/right/Pinky.res" id="23_7vyi4"]
|
||||
[ext_resource type="Animation" uid="uid://csp3fdknowmi5" path="res://addons/godot-xr-tools/hands/animations/right/Pistol.res" id="24_nc600"]
|
||||
[ext_resource type="Animation" uid="uid://2ttepgvf634h" path="res://addons/godot-xr-tools/hands/animations/right/Ring.res" id="25_20nj0"]
|
||||
[ext_resource type="Animation" uid="uid://wcwa3p1qrhwr" path="res://addons/godot-xr-tools/hands/animations/right/Rounded.res" id="26_648rb"]
|
||||
[ext_resource type="Animation" uid="uid://bcwx6a6mhsoj2" path="res://addons/godot-xr-tools/hands/animations/right/Sign 1.res" id="27_liq3y"]
|
||||
[ext_resource type="Animation" uid="uid://btnsp36fjkldf" path="res://addons/godot-xr-tools/hands/animations/right/Sign 2.res" id="28_vdv8x"]
|
||||
[ext_resource type="Animation" uid="uid://c35i6glt1ov2m" path="res://addons/godot-xr-tools/hands/animations/right/Sign 3.res" id="29_uairn"]
|
||||
[ext_resource type="Animation" uid="uid://b8mmk2ufmlyf" path="res://addons/godot-xr-tools/hands/animations/right/Sign 4.res" id="30_351lm"]
|
||||
[ext_resource type="Animation" uid="uid://ddgl3lsnlfiny" path="res://addons/godot-xr-tools/hands/animations/right/Sign 5.res" id="31_o4yst"]
|
||||
[ext_resource type="Animation" uid="uid://ccy3e7a0hvxyl" path="res://addons/godot-xr-tools/hands/animations/right/Sign_Point.res" id="32_02kj7"]
|
||||
[ext_resource type="Animation" uid="uid://d3h36bkauutoq" path="res://addons/godot-xr-tools/hands/animations/right/Straight.res" id="33_gpxgh"]
|
||||
[ext_resource type="Animation" uid="uid://bq7cjxdn28jcv" path="res://addons/godot-xr-tools/hands/animations/right/Surfer.res" id="34_ldn4j"]
|
||||
[ext_resource type="Animation" uid="uid://d2ukhr3n2r1u8" path="res://addons/godot-xr-tools/hands/animations/right/Thumb.res" id="35_xnxq3"]
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_reqae"]
|
||||
_data = {
|
||||
&"Cup": ExtResource("1_mq7eu"),
|
||||
&"Default pose": ExtResource("2_kxlaj"),
|
||||
&"Grip": ExtResource("9_y16mo"),
|
||||
&"Grip 1": ExtResource("3_5xubn"),
|
||||
&"Grip 2": ExtResource("4_y3ovo"),
|
||||
&"Grip 3": ExtResource("5_0d4pg"),
|
||||
&"Grip 4": ExtResource("6_nabm2"),
|
||||
&"Grip 5": ExtResource("7_gy2yb"),
|
||||
&"Grip Shaft": ExtResource("8_ffwxq"),
|
||||
&"Hold": ExtResource("10_g8e21"),
|
||||
&"Horns": ExtResource("11_b3lks"),
|
||||
&"Metal": ExtResource("12_p14fk"),
|
||||
&"Middle": ExtResource("13_4i278"),
|
||||
&"OK": ExtResource("14_qk7tg"),
|
||||
&"Peace": ExtResource("15_ejppt"),
|
||||
&"Pinch Flat": ExtResource("16_7cyln"),
|
||||
&"Pinch Large": ExtResource("17_amtgc"),
|
||||
&"Pinch Middle": ExtResource("18_pnqcq"),
|
||||
&"Pinch Ring": ExtResource("19_aeaff"),
|
||||
&"Pinch Tight": ExtResource("20_mghnf"),
|
||||
&"Pinch Up": ExtResource("21_1v6tw"),
|
||||
&"PingPong": ExtResource("22_ueac0"),
|
||||
&"Pinky": ExtResource("23_7vyi4"),
|
||||
&"Pistol": ExtResource("24_nc600"),
|
||||
&"Ring": ExtResource("25_20nj0"),
|
||||
&"Rounded": ExtResource("26_648rb"),
|
||||
&"Sign 1": ExtResource("27_liq3y"),
|
||||
&"Sign 2": ExtResource("28_vdv8x"),
|
||||
&"Sign 3": ExtResource("29_uairn"),
|
||||
&"Sign 4": ExtResource("30_351lm"),
|
||||
&"Sign 5": ExtResource("31_o4yst"),
|
||||
&"Sign_Point": ExtResource("32_02kj7"),
|
||||
&"Straight": ExtResource("33_gpxgh"),
|
||||
&"Surfer": ExtResource("34_ldn4j"),
|
||||
&"Thumb": ExtResource("35_xnxq3")
|
||||
}
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer"]
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_reqae")
|
||||
}
|
||||
BIN
addons/godot-xr-tools/hands/animations/right/Cup.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Cup.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Default pose.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Default pose.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Grip 1.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Grip 1.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Grip 2.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Grip 2.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Grip 3.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Grip 3.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Grip 4.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Grip 4.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Grip 5.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Grip 5.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Grip Shaft.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Grip Shaft.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Grip.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Grip.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Hold.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Hold.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Horns.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Horns.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Metal.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Metal.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Middle.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Middle.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/OK.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/OK.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Peace.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Peace.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Flat.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Flat.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Large.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Large.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Middle.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Middle.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Ring.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Ring.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Tight.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Tight.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Up.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Pinch Up.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/PingPong.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/PingPong.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Pinky.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Pinky.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Pistol.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Pistol.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Ring.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Ring.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Rounded.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Rounded.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Sign 1.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Sign 1.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Sign 2.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Sign 2.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Sign 3.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Sign 3.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Sign 4.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Sign 4.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Sign 5.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Sign 5.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Sign_Point.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Sign_Point.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Straight.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Straight.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Surfer.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Surfer.res
Normal file
Binary file not shown.
BIN
addons/godot-xr-tools/hands/animations/right/Thumb.res
Normal file
BIN
addons/godot-xr-tools/hands/animations/right/Thumb.res
Normal file
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
[gd_resource type="AnimationNodeBlendTree" load_steps=6 format=3 uid="uid://m85b1gogdums"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="1"]
|
||||
animation = &"Grip"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="2"]
|
||||
animation = &"Grip"
|
||||
|
||||
[sub_resource type="AnimationNodeBlend2" id="4"]
|
||||
filter_enabled = true
|
||||
filters = ["Armature/Skeleton3D:Little_Distal_R", "Armature/Skeleton3D:Little_Intermediate_R", "Armature/Skeleton3D:Little_Metacarpal_R", "Armature/Skeleton3D:Little_Proximal_R", "Armature/Skeleton3D:Middle_Distal_R", "Armature/Skeleton3D:Middle_Intermediate_R", "Armature/Skeleton3D:Middle_Metacarpal_R", "Armature/Skeleton3D:Middle_Proximal_R", "Armature/Skeleton3D:Ring_Distal_R", "Armature/Skeleton3D:Ring_Intermediate_R", "Armature/Skeleton3D:Ring_Metacarpal_R", "Armature/Skeleton3D:Ring_Proximal_R", "Armature/Skeleton3D:Thumb_Distal_R", "Armature/Skeleton3D:Thumb_Metacarpal_R", "Armature/Skeleton3D:Thumb_Proximal_R", "Armature/Skeleton:Little_Distal_R", "Armature/Skeleton:Little_Intermediate_R", "Armature/Skeleton:Little_Proximal_R", "Armature/Skeleton:Middle_Distal_R", "Armature/Skeleton:Middle_Intermediate_R", "Armature/Skeleton:Middle_Proximal_R", "Armature/Skeleton:Ring_Distal_R", "Armature/Skeleton:Ring_Intermediate_R", "Armature/Skeleton:Ring_Proximal_R", "Armature/Skeleton:Thumb_Distal_R", "Armature/Skeleton:Thumb_Proximal_R"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="3"]
|
||||
animation = &"Grip 5"
|
||||
|
||||
[sub_resource type="AnimationNodeBlend2" id="5"]
|
||||
filter_enabled = true
|
||||
filters = ["Armature/Skeleton3D:Index_Distal_R", "Armature/Skeleton3D:Index_Intermediate_R", "Armature/Skeleton3D:Index_Metacarpal_R", "Armature/Skeleton3D:Index_Proximal_R", "Armature/Skeleton:Index_Distal_R", "Armature/Skeleton:Index_Intermediate_R", "Armature/Skeleton:Index_Proximal_R"]
|
||||
|
||||
[resource]
|
||||
graph_offset = Vector2(-552.664, 107.301)
|
||||
nodes/ClosedHand1/node = SubResource("1")
|
||||
nodes/ClosedHand1/position = Vector2(-600, 300)
|
||||
nodes/ClosedHand2/node = SubResource("2")
|
||||
nodes/ClosedHand2/position = Vector2(-360, 300)
|
||||
nodes/Grip/node = SubResource("4")
|
||||
nodes/Grip/position = Vector2(0, 40)
|
||||
nodes/OpenHand/node = SubResource("3")
|
||||
nodes/OpenHand/position = Vector2(-600, 100)
|
||||
nodes/Trigger/node = SubResource("5")
|
||||
nodes/Trigger/position = Vector2(-360, 40)
|
||||
node_connections = [&"output", 0, &"Grip", &"Grip", 0, &"Trigger", &"Grip", 1, &"ClosedHand2", &"Trigger", 0, &"OpenHand", &"Trigger", 1, &"ClosedHand1"]
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
[remap]
|
||||
|
||||
importer="keep"
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
[remap]
|
||||
|
||||
importer="keep"
|
||||
BIN
addons/godot-xr-tools/hands/blend/hand_l.blend
Normal file
BIN
addons/godot-xr-tools/hands/blend/hand_l.blend
Normal file
Binary file not shown.
3
addons/godot-xr-tools/hands/blend/hand_l.blend.import
Normal file
3
addons/godot-xr-tools/hands/blend/hand_l.blend.import
Normal file
@@ -0,0 +1,3 @@
|
||||
[remap]
|
||||
|
||||
importer="keep"
|
||||
BIN
addons/godot-xr-tools/hands/blend/hand_r.blend
Normal file
BIN
addons/godot-xr-tools/hands/blend/hand_r.blend
Normal file
Binary file not shown.
3
addons/godot-xr-tools/hands/blend/hand_r.blend.import
Normal file
3
addons/godot-xr-tools/hands/blend/hand_r.blend.import
Normal file
@@ -0,0 +1,3 @@
|
||||
[remap]
|
||||
|
||||
importer="keep"
|
||||
450
addons/godot-xr-tools/hands/collision_hand.gd
Normal file
450
addons/godot-xr-tools/hands/collision_hand.gd
Normal file
@@ -0,0 +1,450 @@
|
||||
@tool
|
||||
class_name XRToolsCollisionHand
|
||||
extends XRToolsForceBody
|
||||
|
||||
|
||||
## XRTools Collision Hand Container Script
|
||||
##
|
||||
## This script implements logic for collision hands. Specifically it tracks
|
||||
## its ancestor [XRController3D], and can act as a container for hand models
|
||||
## and pickup functions.
|
||||
|
||||
# We reached our teleport distance
|
||||
signal max_distance_reached
|
||||
|
||||
## Modes for collision hand
|
||||
enum CollisionHandMode {
|
||||
## Hand is disabled and must be moved externally
|
||||
DISABLED,
|
||||
|
||||
## Hand teleports to controller
|
||||
TELEPORT,
|
||||
|
||||
## Hand collides with world (based on mask)
|
||||
COLLIDE
|
||||
}
|
||||
|
||||
# Default layer of 18:player-hands
|
||||
const DEFAULT_LAYER := 0b0000_0000_0000_0010_0000_0000_0000_0000
|
||||
|
||||
# Default mask of 0xFFFF (1..16)
|
||||
# - 1:static-world
|
||||
# - 2:dynamic-world
|
||||
# - 3:pickable-objects
|
||||
# - 4:wall-walking
|
||||
# - 5:grappling-target
|
||||
const DEFAULT_MASK := 0b0000_0000_0000_0101_0000_0000_0001_1111
|
||||
|
||||
# How much displacement is required for the hand to start orienting to a surface
|
||||
const ORIENT_DISPLACEMENT := 0.05
|
||||
|
||||
# Distance to teleport hands
|
||||
const TELEPORT_DISTANCE := 1.0
|
||||
|
||||
## Controls the hand collision mode
|
||||
@export var mode : CollisionHandMode = CollisionHandMode.COLLIDE
|
||||
|
||||
|
||||
## Links to skeleton that adds finger digits
|
||||
@export var hand_skeleton : Skeleton3D:
|
||||
set(value):
|
||||
if hand_skeleton == value:
|
||||
return
|
||||
|
||||
if hand_skeleton:
|
||||
if hand_skeleton.has_signal("skeleton_updated"):
|
||||
# Godot 4.3+
|
||||
hand_skeleton.skeleton_updated.disconnect(_on_skeleton_updated)
|
||||
else:
|
||||
hand_skeleton.pose_updated.disconnect(_on_skeleton_updated)
|
||||
for digit in _digit_collision_shapes:
|
||||
var shape : CollisionShape3D = _digit_collision_shapes[digit]
|
||||
remove_child(shape)
|
||||
shape.queue_free()
|
||||
_digit_collision_shapes.clear()
|
||||
|
||||
hand_skeleton = value
|
||||
if hand_skeleton and is_inside_tree():
|
||||
_update_hand_skeleton()
|
||||
|
||||
notify_property_list_changed()
|
||||
|
||||
|
||||
## Minimum force we can exert on a picked up object
|
||||
@export_range(1.0, 1000.0, 0.1, "suffix:N") var min_pickup_force : float = 15.0
|
||||
|
||||
## Force we exert on a picked up object when hand is at maximum distance
|
||||
## before letting go.
|
||||
@export_range(1.0, 1000.0, 0.1, "suffix:N") var max_pickup_force : float = 300.0
|
||||
|
||||
|
||||
# Controller to target (if no target overrides)
|
||||
var _controller : XRController3D
|
||||
|
||||
# Sorted stack of TargetOverride
|
||||
var _target_overrides := []
|
||||
|
||||
# Current target (controller or override)
|
||||
var _target : Node3D
|
||||
|
||||
# Skeleton collisions
|
||||
var _palm_collision_shape : CollisionShape3D
|
||||
var _digit_collision_shapes : Dictionary
|
||||
|
||||
# The weight held by this hand
|
||||
var _held_weight : float = 0.0
|
||||
|
||||
# Movement on last frame
|
||||
var _last_movement : Vector3 = Vector3()
|
||||
|
||||
## Target-override class
|
||||
class TargetOverride:
|
||||
## Target of the override
|
||||
var target : Node3D
|
||||
|
||||
## Target priority
|
||||
var priority : int
|
||||
|
||||
## Target-override constructor
|
||||
func _init(t : Node3D, p : int):
|
||||
target = t
|
||||
priority = p
|
||||
|
||||
|
||||
# Update the weight attributed to this hand (updated from pickable system).
|
||||
func set_held_weight(new_weight):
|
||||
_held_weight = new_weight
|
||||
|
||||
|
||||
# Add support for is_xr_class on XRTools classes
|
||||
func is_xr_class(xr_name: String) -> bool:
|
||||
return xr_name == "XRToolsCollisionHand"
|
||||
|
||||
|
||||
# Return warnings related to this node
|
||||
func _get_configuration_warnings() -> PackedStringArray:
|
||||
var warnings := PackedStringArray()
|
||||
|
||||
# Check palm node
|
||||
if not _palm_collision_shape:
|
||||
warnings.push_back("Collision hand scenes are deprecated, use collision node script directly.")
|
||||
|
||||
# Check if skeleton is a child
|
||||
if hand_skeleton and not is_ancestor_of(hand_skeleton):
|
||||
warnings.push_back("The hand skeleton node should be within the tree of this node.")
|
||||
|
||||
# Return warnings
|
||||
return warnings
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
var palm_collision : CollisionShape3D = get_node_or_null("CollisionShape3D")
|
||||
if not palm_collision:
|
||||
# We create our object even in editor to supress our warning.
|
||||
# This allows us to just add an XRToolsCollisionHand node without
|
||||
# using our scene.
|
||||
_palm_collision_shape = CollisionShape3D.new()
|
||||
_palm_collision_shape.name = "Palm"
|
||||
_palm_collision_shape.shape = \
|
||||
preload("res://addons/godot-xr-tools/hands/scenes/collision/hand_palm.shape")
|
||||
_palm_collision_shape.transform.origin = Vector3(0.0, -0.05, 0.11)
|
||||
add_child(_palm_collision_shape, false, Node.INTERNAL_MODE_BACK)
|
||||
elif not Engine.is_editor_hint():
|
||||
# Use our existing collision shape node but only in runtime.
|
||||
# In editor we can check this to provide a deprecation warning.
|
||||
palm_collision.name = "Palm"
|
||||
_palm_collision_shape = palm_collision
|
||||
|
||||
_update_hand_skeleton()
|
||||
|
||||
# Do not initialise if in the editor
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
||||
# Disconnect from parent transform as we move to it in the physics step,
|
||||
# and boost the physics priority above any grab-drivers or hands.
|
||||
top_level = true
|
||||
process_physics_priority = -90
|
||||
sync_to_physics = false
|
||||
|
||||
# Connect to player body signals (if applicable)
|
||||
var player_body = XRToolsPlayerBody.find_instance(self)
|
||||
if player_body:
|
||||
player_body.player_moved.connect(_on_player_moved)
|
||||
player_body.player_teleported.connect(_on_player_teleported)
|
||||
|
||||
# Populate nodes
|
||||
_controller = XRTools.find_xr_ancestor(self, "*", "XRController3D")
|
||||
|
||||
# Update the target
|
||||
_update_target()
|
||||
|
||||
|
||||
# Handle physics processing
|
||||
func _physics_process(delta):
|
||||
# Do not process if in the editor
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
||||
var current_position = global_position
|
||||
|
||||
# Move to the current target
|
||||
_move_to_target(delta)
|
||||
|
||||
_last_movement = global_position - current_position
|
||||
|
||||
## This function adds a target override. The collision hand will attempt to
|
||||
## move to the highest priority target, or the [XRController3D] if no override
|
||||
## is specified.
|
||||
func add_target_override(target : Node3D, priority : int) -> void:
|
||||
# Remove any existing target override from this source
|
||||
var modified := _remove_target_override(target)
|
||||
|
||||
# Insert the target override
|
||||
_insert_target_override(target, priority)
|
||||
modified = true
|
||||
|
||||
# Update the target
|
||||
if modified:
|
||||
_update_target()
|
||||
|
||||
|
||||
## This function remove a target override.
|
||||
func remove_target_override(target : Node3D) -> void:
|
||||
# Remove the target override
|
||||
var modified := _remove_target_override(target)
|
||||
|
||||
# Update the pose
|
||||
if modified:
|
||||
_update_target()
|
||||
|
||||
|
||||
## This function searches from the specified node for an [XRToolsCollisionHand]
|
||||
## assuming the node is a sibling of the hand under an [XRController3D].
|
||||
static func find_instance(node : Node) -> XRToolsCollisionHand:
|
||||
return XRTools.find_xr_child(
|
||||
XRHelpers.get_xr_controller(node),
|
||||
"*",
|
||||
"XRToolsCollisionHand") as XRToolsCollisionHand
|
||||
|
||||
## This function searches an [XRToolsCollisionHand] that is an ancestor
|
||||
## of the given node.
|
||||
static func find_ancestor(node : Node) -> XRToolsCollisionHand:
|
||||
return XRTools.find_xr_ancestor(
|
||||
node,
|
||||
"*",
|
||||
"XRToolsCollisionHand") as XRToolsCollisionHand
|
||||
|
||||
|
||||
## This function searches from the specified node for the left controller
|
||||
## [XRToolsCollisionHand] assuming the node is a sibling of the [XROrigin3D].
|
||||
static func find_left(node : Node) -> XRToolsCollisionHand:
|
||||
return XRTools.find_xr_child(
|
||||
XRHelpers.get_left_controller(node),
|
||||
"*",
|
||||
"XRToolsCollisionHand") as XRToolsCollisionHand
|
||||
|
||||
|
||||
## This function searches from the specified node for the right controller
|
||||
## [XRToolsCollisionHand] assuming the node is a sibling of the [XROrigin3D].
|
||||
static func find_right(node : Node) -> XRToolsCollisionHand:
|
||||
return XRTools.find_xr_child(
|
||||
XRHelpers.get_right_controller(node),
|
||||
"*",
|
||||
"XRToolsCollisionHand") as XRToolsCollisionHand
|
||||
|
||||
|
||||
# This function moves the collision hand to the target node.
|
||||
func _move_to_target(delta):
|
||||
# Handle DISABLED or no target
|
||||
if mode == CollisionHandMode.DISABLED or not _target:
|
||||
return
|
||||
|
||||
# Handle TELEPORT
|
||||
if mode == CollisionHandMode.TELEPORT:
|
||||
global_transform = _target.global_transform
|
||||
return
|
||||
|
||||
# Handle too far from target
|
||||
if global_position.distance_to(_target.global_position) > TELEPORT_DISTANCE:
|
||||
max_distance_reached.emit()
|
||||
|
||||
global_transform = _target.global_transform
|
||||
return
|
||||
|
||||
# Orient the hand
|
||||
rotate_and_collide(_target.global_basis)
|
||||
|
||||
# Adjust target position if we're holding something
|
||||
var target_movement : Vector3 = _target.global_position - global_position
|
||||
if _held_weight > 0.0:
|
||||
var gravity_state := PhysicsServer3D.body_get_direct_state(get_rid())
|
||||
var gravity = gravity_state.total_gravity * delta
|
||||
|
||||
# Calculate the movement of our held object if we weren't holding it
|
||||
var base_movement : Vector3 = _last_movement * 0.2 + gravity
|
||||
|
||||
# How much movement is left until we reach our target
|
||||
var remaining_movement = target_movement - base_movement
|
||||
|
||||
# The below is an approximation as we're not taking the logarithmic
|
||||
# nature of force acceleration into account for simplicitiy.
|
||||
|
||||
# Distance over time gives our needed acceleration which
|
||||
# gives us the force needed on the object to move it to our
|
||||
# target destination.
|
||||
# But dividing and then multiplying over delta and mass is wasteful.
|
||||
var needed_distance = remaining_movement.length()
|
||||
|
||||
# Force we can exert on the object
|
||||
var force = min_pickup_force + \
|
||||
(target_movement.length() * (max_pickup_force-min_pickup_force) / TELEPORT_DISTANCE)
|
||||
|
||||
# How much can we move our object?
|
||||
var possible_distance = delta * force / _held_weight
|
||||
if possible_distance < needed_distance:
|
||||
# We can't make our distance? adjust our movement!
|
||||
remaining_movement *= (possible_distance / needed_distance)
|
||||
target_movement = base_movement + remaining_movement
|
||||
|
||||
# And move
|
||||
move_and_slide(target_movement)
|
||||
force_update_transform()
|
||||
|
||||
|
||||
# If our player moved, attempt to move our hand but ignoring weight.
|
||||
func _on_player_moved(delta_transform : Transform3D):
|
||||
if mode == CollisionHandMode.DISABLED:
|
||||
return
|
||||
|
||||
if mode == CollisionHandMode.TELEPORT:
|
||||
_on_player_teleported(delta_transform)
|
||||
return
|
||||
|
||||
var target : Transform3D = delta_transform * global_transform
|
||||
|
||||
# Rotate
|
||||
rotate_and_collide(target.basis)
|
||||
|
||||
# And attempt to move
|
||||
move_and_slide(target.origin - global_position)
|
||||
force_update_transform()
|
||||
|
||||
|
||||
# If our player teleported, just move.
|
||||
func _on_player_teleported(delta_transform : Transform3D):
|
||||
if mode == CollisionHandMode.DISABLED:
|
||||
return
|
||||
|
||||
global_transform = delta_transform * global_transform
|
||||
force_update_transform()
|
||||
|
||||
|
||||
# This function inserts a target override into the overrides list by priority
|
||||
# order.
|
||||
func _insert_target_override(target : Node3D, priority : int) -> void:
|
||||
# Construct the target override
|
||||
var override := TargetOverride.new(target, priority)
|
||||
|
||||
# Iterate over all target overrides in the list
|
||||
for pos in _target_overrides.size():
|
||||
# Get the target override
|
||||
var o : TargetOverride = _target_overrides[pos]
|
||||
|
||||
# Insert as early as possible to not invalidate sorting
|
||||
if o.priority <= priority:
|
||||
_target_overrides.insert(pos, override)
|
||||
return
|
||||
|
||||
# Insert at the end
|
||||
_target_overrides.push_back(override)
|
||||
|
||||
|
||||
# This function removes a target from the overrides list
|
||||
func _remove_target_override(target : Node) -> bool:
|
||||
var pos := 0
|
||||
var length := _target_overrides.size()
|
||||
var modified := false
|
||||
|
||||
# Iterate over all pose overrides in the list
|
||||
while pos < length:
|
||||
# Get the target override
|
||||
var o : TargetOverride = _target_overrides[pos]
|
||||
|
||||
# Check for a match
|
||||
if o.target == target:
|
||||
# Remove the override
|
||||
_target_overrides.remove_at(pos)
|
||||
modified = true
|
||||
length -= 1
|
||||
else:
|
||||
# Advance down the list
|
||||
pos += 1
|
||||
|
||||
# Return the modified indicator
|
||||
return modified
|
||||
|
||||
|
||||
# This function updates the target for hand movement.
|
||||
func _update_target() -> void:
|
||||
# Start by assuming the controller
|
||||
_target = _controller
|
||||
|
||||
# Use first target override if specified
|
||||
if _target_overrides.size():
|
||||
_target = _target_overrides[0].target
|
||||
|
||||
|
||||
# If a skeleton is set, update.
|
||||
func _update_hand_skeleton():
|
||||
if hand_skeleton:
|
||||
if hand_skeleton.has_signal("skeleton_updated"):
|
||||
# Godot 4.3+
|
||||
hand_skeleton.skeleton_updated.connect(_on_skeleton_updated)
|
||||
else:
|
||||
hand_skeleton.pose_updated.connect(_on_skeleton_updated)
|
||||
|
||||
# Run atleast once to init
|
||||
_on_skeleton_updated()
|
||||
|
||||
|
||||
# Update our finger digits when our skeleton updates
|
||||
func _on_skeleton_updated():
|
||||
if not hand_skeleton:
|
||||
return
|
||||
|
||||
var bone_count = hand_skeleton.get_bone_count()
|
||||
for i in bone_count:
|
||||
var collision_node : CollisionShape3D
|
||||
var offset : Transform3D
|
||||
offset.origin = Vector3(0.0, 0.015, 0.0) # move to side of joint
|
||||
|
||||
var bone_name = hand_skeleton.get_bone_name(i)
|
||||
if bone_name == "Palm_L":
|
||||
offset.origin = Vector3(-0.02, 0.025, 0.0) # move to side of joint
|
||||
collision_node = _palm_collision_shape
|
||||
elif bone_name == "Palm_R":
|
||||
offset.origin = Vector3(0.02, 0.025, 0.0) # move to side of joint
|
||||
collision_node = _palm_collision_shape
|
||||
elif bone_name.contains("Proximal") or bone_name.contains("Intermediate") or \
|
||||
bone_name.contains("Distal"):
|
||||
if _digit_collision_shapes.has(bone_name):
|
||||
collision_node = _digit_collision_shapes[bone_name]
|
||||
else:
|
||||
collision_node = CollisionShape3D.new()
|
||||
collision_node.name = bone_name
|
||||
collision_node.shape = \
|
||||
preload("res://addons/godot-xr-tools/hands/scenes/collision/hand_digit.shape")
|
||||
add_child(collision_node, false, Node.INTERNAL_MODE_BACK)
|
||||
_digit_collision_shapes[bone_name] = collision_node
|
||||
|
||||
if collision_node:
|
||||
# TODO it would require a far more complex approach,
|
||||
# but being able to check if our collision shapes can move to their new locations
|
||||
# would be interesting.
|
||||
|
||||
collision_node.transform = global_transform.inverse() \
|
||||
* hand_skeleton.global_transform \
|
||||
* hand_skeleton.get_bone_global_pose(i) \
|
||||
* offset
|
||||
1
addons/godot-xr-tools/hands/collision_hand.gd.uid
Normal file
1
addons/godot-xr-tools/hands/collision_hand.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c8vnltn217quj
|
||||
505
addons/godot-xr-tools/hands/hand.gd
Normal file
505
addons/godot-xr-tools/hands/hand.gd
Normal file
@@ -0,0 +1,505 @@
|
||||
@tool
|
||||
@icon("res://addons/godot-xr-tools/editor/icons/hand.svg")
|
||||
class_name XRToolsHand
|
||||
extends XRToolsHandPalmOffset
|
||||
|
||||
|
||||
## XR Tools Hand Script
|
||||
##
|
||||
## This script manages a godot-xr-tools hand. It animates the hand blending
|
||||
## grip and trigger animations based on controller input.
|
||||
##
|
||||
## Additionally the hand script detects world-scale changes in the XRServer
|
||||
## and re-scales the hand appropriately so the hand stays scaled to the
|
||||
## physical hand of the user.
|
||||
|
||||
|
||||
## Signal emitted when the hand scale changes
|
||||
signal hand_scale_changed(scale)
|
||||
|
||||
## Blend tree to use
|
||||
@export var hand_blend_tree : AnimationNodeBlendTree: set = set_hand_blend_tree
|
||||
|
||||
## Override the hand material
|
||||
@export var hand_material_override : Material: set = set_hand_material_override
|
||||
|
||||
## Default hand pose
|
||||
@export var default_pose : XRToolsHandPoseSettings: set = set_default_pose
|
||||
|
||||
## Name of the Grip action in the OpenXR Action Map.
|
||||
@export var grip_action : String = "grip"
|
||||
|
||||
## Name of the Trigger action in the OpenXR Action Map.
|
||||
@export var trigger_action : String = "trigger"
|
||||
|
||||
## Last world scale (for scaling hands)
|
||||
var _last_world_scale : float = 1.0
|
||||
|
||||
## Initial hand transform (from controller) - used for scaling hands
|
||||
var _initial_transform : Transform3D
|
||||
|
||||
## Current hand transform (from controller) - after scale
|
||||
var _transform : Transform3D
|
||||
|
||||
## Hand mesh
|
||||
var _hand_mesh : MeshInstance3D
|
||||
|
||||
## Hand animation player
|
||||
var _animation_player : AnimationPlayer
|
||||
|
||||
## Hand animation tree
|
||||
var _animation_tree : AnimationTree
|
||||
|
||||
## Animation blend tree
|
||||
var _tree_root : AnimationNodeBlendTree
|
||||
|
||||
## Sorted stack of PoseOverride
|
||||
var _pose_overrides := []
|
||||
|
||||
## Force grip value (< 0 for no force)
|
||||
var _force_grip := -1.0
|
||||
|
||||
## Force trigger value (< 0 for no force)
|
||||
var _force_trigger := -1.0
|
||||
|
||||
# Sorted stack of TargetOverride
|
||||
var _target_overrides := []
|
||||
|
||||
# Current target (controller or override)
|
||||
var _target : Node3D
|
||||
|
||||
|
||||
## Pose-override class
|
||||
class PoseOverride:
|
||||
## Who requested the override
|
||||
var who : Node
|
||||
|
||||
## Pose priority
|
||||
var priority : int
|
||||
|
||||
## Pose settings
|
||||
var settings : XRToolsHandPoseSettings
|
||||
|
||||
## Pose-override constructor
|
||||
func _init(w : Node, p : int, s : XRToolsHandPoseSettings):
|
||||
who = w
|
||||
priority = p
|
||||
settings = s
|
||||
|
||||
|
||||
## Target-override class
|
||||
class TargetOverride:
|
||||
## Target of the override
|
||||
var target : Node3D
|
||||
|
||||
## Target priority
|
||||
var priority : int
|
||||
|
||||
## Target-override constructor
|
||||
func _init(t : Node3D, p : int):
|
||||
target = t
|
||||
priority = p
|
||||
|
||||
|
||||
# Add support for is_xr_class on XRTools classes
|
||||
func is_xr_class(xr_name: String) -> bool:
|
||||
return xr_name == "XRToolsHand"
|
||||
|
||||
|
||||
## Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
# Save the initial hand transform
|
||||
_initial_transform = transform
|
||||
_transform = _initial_transform
|
||||
|
||||
# Disconnect from parent transform as we move to it in the physics step,
|
||||
# and boost the physics priority after any grab-drivers but before other
|
||||
# processing.
|
||||
if not Engine.is_editor_hint():
|
||||
top_level = true
|
||||
process_physics_priority = -70
|
||||
|
||||
# Find the relevant hand nodes
|
||||
_hand_mesh = _find_child(self, "MeshInstance3D")
|
||||
_animation_player = _find_child(self, "AnimationPlayer")
|
||||
_animation_tree = _find_child(self, "AnimationTree")
|
||||
|
||||
# Apply all updates
|
||||
_update_hand_blend_tree()
|
||||
_update_hand_material_override()
|
||||
_update_pose()
|
||||
_update_target()
|
||||
|
||||
|
||||
# Called when we get added to our tree
|
||||
func _enter_tree():
|
||||
# Assume our first child is our hand subscene, we position this
|
||||
var child = get_child(0)
|
||||
if child:
|
||||
set_apply_to(child)
|
||||
|
||||
super._enter_tree()
|
||||
|
||||
# Offset our hand
|
||||
var base_transform = Transform3D()
|
||||
if _controller and _controller.tracker == "left_hand":
|
||||
base_transform.origin = Vector3(-0.01, 0.0, 0.05)
|
||||
else:
|
||||
base_transform.origin = Vector3(0.01, 0.0, 0.05)
|
||||
|
||||
set_base_transform(base_transform)
|
||||
|
||||
|
||||
## This method checks for world-scale changes and scales itself causing the
|
||||
## hand mesh and skeleton to scale appropriately. It then reads the grip and
|
||||
## trigger action values to animate the hand.
|
||||
func _physics_process(_delta: float) -> void:
|
||||
# Do not run the rest of physics if in the editor
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
||||
# Scale the hand mesh with the world scale.
|
||||
if XRServer.world_scale != _last_world_scale:
|
||||
_last_world_scale = XRServer.world_scale
|
||||
_transform = _initial_transform.scaled(Vector3.ONE * _last_world_scale)
|
||||
emit_signal("hand_scale_changed", _last_world_scale)
|
||||
|
||||
# Animate the hand mesh with the controller inputs
|
||||
if _controller:
|
||||
var grip : float = _controller.get_float(grip_action)
|
||||
var trigger : float = _controller.get_float(trigger_action)
|
||||
|
||||
# Allow overriding of grip and trigger
|
||||
if _force_grip >= 0.0: grip = _force_grip
|
||||
if _force_trigger >= 0.0: trigger = _force_trigger
|
||||
|
||||
$AnimationTree.set("parameters/Grip/blend_amount", grip)
|
||||
$AnimationTree.set("parameters/Trigger/blend_amount", trigger)
|
||||
|
||||
# Move to target
|
||||
var target_transform : Transform3D
|
||||
if _target is XRToolsGrabPointHand:
|
||||
target_transform = _target.get_palm_transform(true)
|
||||
if hand_offset_mode != 4:
|
||||
target_transform = target_transform * XRTools.get_palm_offset(hand_offset_mode, _controller).inverse()
|
||||
else:
|
||||
target_transform = _target.global_transform
|
||||
|
||||
global_transform = target_transform * _transform
|
||||
force_update_transform()
|
||||
|
||||
|
||||
# This method verifies the hand has a valid configuration.
|
||||
func _get_configuration_warnings() -> PackedStringArray:
|
||||
var warnings : PackedStringArray = super._get_configuration_warnings()
|
||||
|
||||
# Check hand for mesh instance
|
||||
if not _find_child(self, "MeshInstance3D"):
|
||||
warnings.append("Hand does not have a MeshInstance3D")
|
||||
|
||||
# Check hand for animation player
|
||||
if not _find_child(self, "AnimationPlayer"):
|
||||
warnings.append("Hand does not have a AnimationPlayer")
|
||||
|
||||
# Check hand for animation tree
|
||||
var tree : AnimationTree = _find_child(self, "AnimationTree")
|
||||
if not tree:
|
||||
warnings.append("Hand does not have a AnimationTree")
|
||||
elif not tree.tree_root:
|
||||
warnings.append("Hand AnimationTree has no root")
|
||||
|
||||
# Return warnings
|
||||
return warnings
|
||||
|
||||
|
||||
## Find an [XRToolsHand] node.
|
||||
##
|
||||
## This function searches from the specified node for an [XRToolsHand] assuming
|
||||
## the node is a sibling of the hand under an [XROrigin3D].
|
||||
static func find_instance(node : Node) -> XRToolsHand:
|
||||
return XRTools.find_xr_child(
|
||||
XRHelpers.get_xr_controller(node),
|
||||
"*",
|
||||
"XRToolsHand") as XRToolsHand
|
||||
|
||||
|
||||
## This function searches from the specified node for the left controller
|
||||
## [XRToolsHand] assuming the node is a sibling of the [XROrigin3D].
|
||||
static func find_left(node : Node) -> XRToolsHand:
|
||||
return XRTools.find_xr_child(
|
||||
XRHelpers.get_left_controller(node),
|
||||
"*",
|
||||
"XRToolsHand") as XRToolsHand
|
||||
|
||||
|
||||
## This function searches from the specified node for the right controller
|
||||
## [XRToolsHand] assuming the node is a sibling of the [XROrigin3D].
|
||||
static func find_right(node : Node) -> XRToolsHand:
|
||||
return XRTools.find_xr_child(
|
||||
XRHelpers.get_right_controller(node),
|
||||
"*",
|
||||
"XRToolsHand") as XRToolsHand
|
||||
|
||||
|
||||
# Check property config
|
||||
func _validate_property(property):
|
||||
if property.name == "top_level":
|
||||
# Hide it!
|
||||
property.usage = PROPERTY_USAGE_NONE
|
||||
else:
|
||||
super._validate_property(property)
|
||||
|
||||
|
||||
## Set the blend tree
|
||||
func set_hand_blend_tree(blend_tree : AnimationNodeBlendTree) -> void:
|
||||
hand_blend_tree = blend_tree
|
||||
if is_inside_tree():
|
||||
_update_hand_blend_tree()
|
||||
_update_pose()
|
||||
|
||||
|
||||
## Set the hand material override
|
||||
func set_hand_material_override(material : Material) -> void:
|
||||
hand_material_override = material
|
||||
if is_inside_tree():
|
||||
_update_hand_material_override()
|
||||
|
||||
|
||||
## Set the default open-hand pose
|
||||
func set_default_pose(pose : XRToolsHandPoseSettings) -> void:
|
||||
default_pose = pose
|
||||
if is_inside_tree():
|
||||
_update_pose()
|
||||
|
||||
|
||||
## Add a pose override
|
||||
func add_pose_override(who : Node, priority : int, settings : XRToolsHandPoseSettings) -> void:
|
||||
# Remove any existing pose override from this source
|
||||
var modified := _remove_pose_override(who)
|
||||
|
||||
# Insert the pose override
|
||||
if settings:
|
||||
_insert_pose_override(who, priority, settings)
|
||||
modified = true
|
||||
|
||||
# Update the pose
|
||||
if modified:
|
||||
_update_pose()
|
||||
|
||||
|
||||
## Remove a pose override
|
||||
func remove_pose_override(who : Node) -> void:
|
||||
# Remove the pose override
|
||||
var modified := _remove_pose_override(who)
|
||||
|
||||
# Update the pose
|
||||
if modified:
|
||||
_update_pose()
|
||||
|
||||
|
||||
## Force the grip and trigger values (primarily for preview)
|
||||
func force_grip_trigger(grip : float = -1.0, trigger : float = -1.0) -> void:
|
||||
# Save the forced values
|
||||
_force_grip = grip
|
||||
_force_trigger = trigger
|
||||
|
||||
# Update the animation if forcing to specific values
|
||||
if grip >= 0.0: $AnimationTree.set("parameters/Grip/blend_amount", grip)
|
||||
if trigger >= 0.0: $AnimationTree.set("parameters/Trigger/blend_amount", trigger)
|
||||
|
||||
|
||||
## This function adds a target override. The collision hand will attempt to
|
||||
## move to the highest priority target, or the [XRController3D] if no override
|
||||
## is specified.
|
||||
func add_target_override(target : Node3D, priority : int) -> void:
|
||||
# Remove any existing target override from this source
|
||||
var modified := _remove_target_override(target)
|
||||
|
||||
# Insert the target override
|
||||
_insert_target_override(target, priority)
|
||||
modified = true
|
||||
|
||||
# Update the target
|
||||
if modified:
|
||||
_update_target()
|
||||
|
||||
|
||||
## This function remove a target override.
|
||||
func remove_target_override(target : Node3D) -> void:
|
||||
# Remove the target override
|
||||
var modified := _remove_target_override(target)
|
||||
|
||||
# Update the pose
|
||||
if modified:
|
||||
_update_target()
|
||||
|
||||
|
||||
func _update_hand_blend_tree() -> void:
|
||||
# As we're going to make modifications to our animation tree, we need to do
|
||||
# a deep copy, simply setting resource local to scene does not seem to be enough
|
||||
if _animation_tree and hand_blend_tree:
|
||||
_tree_root = hand_blend_tree.duplicate(true)
|
||||
_animation_tree.tree_root = _tree_root
|
||||
|
||||
|
||||
func _update_hand_material_override() -> void:
|
||||
if _hand_mesh:
|
||||
_hand_mesh.material_override = hand_material_override
|
||||
|
||||
|
||||
func _update_pose() -> void:
|
||||
# Skip if no blend tree
|
||||
if !_tree_root:
|
||||
return
|
||||
|
||||
# Select the pose settings
|
||||
var pose_settings : XRToolsHandPoseSettings = default_pose
|
||||
if _pose_overrides.size():
|
||||
pose_settings = _pose_overrides[0].settings
|
||||
|
||||
# Get the open and closed pose animations
|
||||
var open_pose : Animation = pose_settings.open_pose
|
||||
var closed_pose : Animation = pose_settings.closed_pose
|
||||
|
||||
# Apply the open hand pose in the player and blend tree
|
||||
if open_pose:
|
||||
var open_name = _animation_player.find_animation(open_pose)
|
||||
if open_name == "":
|
||||
open_name = "open_hand"
|
||||
if _animation_player.has_animation(open_name):
|
||||
_animation_player.get_animation_library("").remove_animation(open_name)
|
||||
|
||||
_animation_player.get_animation_library("").add_animation(open_name, open_pose)
|
||||
|
||||
var open_hand_obj : AnimationNodeAnimation = _tree_root.get_node("OpenHand")
|
||||
if open_hand_obj:
|
||||
open_hand_obj.animation = open_name
|
||||
|
||||
# Apply the closed hand pose in the player and blend tree
|
||||
if closed_pose:
|
||||
var closed_name = _animation_player.find_animation(closed_pose)
|
||||
if closed_name == "":
|
||||
closed_name = "closed_hand"
|
||||
if _animation_player.has_animation(closed_name):
|
||||
_animation_player.get_animation_library("").remove_animation(closed_name)
|
||||
|
||||
_animation_player.get_animation_library("").add_animation(closed_name, closed_pose)
|
||||
|
||||
var closed_hand_obj : AnimationNodeAnimation = _tree_root.get_node("ClosedHand1")
|
||||
if closed_hand_obj:
|
||||
closed_hand_obj.animation = closed_name
|
||||
|
||||
closed_hand_obj = _tree_root.get_node("ClosedHand2")
|
||||
if closed_hand_obj:
|
||||
closed_hand_obj.animation = closed_name
|
||||
|
||||
|
||||
func _insert_pose_override(who : Node, priority : int, settings : XRToolsHandPoseSettings) -> void:
|
||||
# Construct the pose override
|
||||
var override := PoseOverride.new(who, priority, settings)
|
||||
|
||||
# Iterate over all pose overrides in the list
|
||||
for pos in _pose_overrides.size():
|
||||
# Get the pose override
|
||||
var pose : PoseOverride = _pose_overrides[pos]
|
||||
|
||||
# Insert as early as possible to not invalidate sorting
|
||||
if pose.priority <= priority:
|
||||
_pose_overrides.insert(pos, override)
|
||||
return
|
||||
|
||||
# Insert at the end
|
||||
_pose_overrides.push_back(override)
|
||||
|
||||
|
||||
func _remove_pose_override(who : Node) -> bool:
|
||||
var pos := 0
|
||||
var length := _pose_overrides.size()
|
||||
var modified := false
|
||||
|
||||
# Iterate over all pose overrides in the list
|
||||
while pos < length:
|
||||
# Get the pose override
|
||||
var pose : PoseOverride = _pose_overrides[pos]
|
||||
|
||||
# Check for a match
|
||||
if pose.who == who:
|
||||
# Remove the override
|
||||
_pose_overrides.remove_at(pos)
|
||||
modified = true
|
||||
length -= 1
|
||||
else:
|
||||
# Advance down the list
|
||||
pos += 1
|
||||
|
||||
# Return the modified indicator
|
||||
return modified
|
||||
|
||||
|
||||
# This function inserts a target override into the overrides list by priority
|
||||
# order.
|
||||
func _insert_target_override(target : Node3D, priority : int) -> void:
|
||||
# Construct the target override
|
||||
var override := TargetOverride.new(target, priority)
|
||||
|
||||
# Iterate over all target overrides in the list
|
||||
for pos in _target_overrides.size():
|
||||
# Get the target override
|
||||
var o : TargetOverride = _target_overrides[pos]
|
||||
|
||||
# Insert as early as possible to not invalidate sorting
|
||||
if o.priority <= priority:
|
||||
_target_overrides.insert(pos, override)
|
||||
return
|
||||
|
||||
# Insert at the end
|
||||
_target_overrides.push_back(override)
|
||||
|
||||
|
||||
# This function removes a target from the overrides list
|
||||
func _remove_target_override(target : Node) -> bool:
|
||||
var pos := 0
|
||||
var length := _target_overrides.size()
|
||||
var modified := false
|
||||
|
||||
# Iterate over all pose overrides in the list
|
||||
while pos < length:
|
||||
# Get the target override
|
||||
var o : TargetOverride = _target_overrides[pos]
|
||||
|
||||
# Check for a match
|
||||
if o.target == target:
|
||||
# Remove the override
|
||||
_target_overrides.remove_at(pos)
|
||||
modified = true
|
||||
length -= 1
|
||||
else:
|
||||
# Advance down the list
|
||||
pos += 1
|
||||
|
||||
# Return the modified indicator
|
||||
return modified
|
||||
|
||||
|
||||
# This function updates the target for hand movement.
|
||||
func _update_target() -> void:
|
||||
if _target_overrides.size():
|
||||
_target = _target_overrides[0].target
|
||||
else:
|
||||
_target = get_parent()
|
||||
|
||||
|
||||
static func _find_child(node : Node, type : String) -> Node:
|
||||
# Iterate through all children
|
||||
for child in node.get_children():
|
||||
# If the child is a match then return it
|
||||
if child.is_class(type):
|
||||
return child
|
||||
|
||||
# Recurse into child
|
||||
var found := _find_child(child, type)
|
||||
if found:
|
||||
return found
|
||||
|
||||
# No child found matching type
|
||||
return null
|
||||
1
addons/godot-xr-tools/hands/hand.gd.uid
Normal file
1
addons/godot-xr-tools/hands/hand.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cnwtovj4mqc45
|
||||
96
addons/godot-xr-tools/hands/hand_aim_offset.gd
Normal file
96
addons/godot-xr-tools/hands/hand_aim_offset.gd
Normal file
@@ -0,0 +1,96 @@
|
||||
@tool
|
||||
class_name XRToolsHandAimOffset
|
||||
extends Node3D
|
||||
|
||||
## XRToolsHandAimOffset will automatically adjust its position,
|
||||
## to the aim position (within limits).
|
||||
|
||||
## Hand offset to apply based on our controller pose
|
||||
## You can use auto if you're using the default aim_pose or grip_pose poses.
|
||||
@export_enum("auto", "aim", "grip", "palm", "disable") var hand_offset_mode : int = 0:
|
||||
set(value):
|
||||
hand_offset_mode = value
|
||||
notify_property_list_changed()
|
||||
if is_inside_tree():
|
||||
_update_transform()
|
||||
|
||||
# Controller
|
||||
var _controller : XRController3D
|
||||
|
||||
# Keep track of our tracker and pose
|
||||
var _controller_tracker_and_pose : String = ""
|
||||
|
||||
# Which node are we applying our transform on?
|
||||
var _apply_to : Node3D
|
||||
|
||||
# Additional transform to apply
|
||||
var _base_transform : Transform3D = Transform3D()
|
||||
|
||||
## Add support for is_xr_class on XRTools classes
|
||||
func is_xr_class(xr_name: String) -> bool:
|
||||
return xr_name == "XRToolsHandAimOffset"
|
||||
|
||||
|
||||
## Set the node we apply our transform to
|
||||
## Must be set before _enter_tree is called for the first time.
|
||||
func set_apply_to(node : Node3D) -> void:
|
||||
_apply_to = node
|
||||
|
||||
|
||||
## Set a base transform to apply
|
||||
func set_base_transform(base_transform : Transform3D) -> void:
|
||||
_base_transform = base_transform
|
||||
if is_inside_tree():
|
||||
_update_transform()
|
||||
|
||||
|
||||
# Called when we're added to the tree
|
||||
func _enter_tree():
|
||||
if not _apply_to:
|
||||
_apply_to = self
|
||||
|
||||
_controller = XRHelpers.get_xr_controller(self)
|
||||
|
||||
_update_transform()
|
||||
|
||||
|
||||
# Called when we exit the tree
|
||||
func _exit_tree():
|
||||
if _controller:
|
||||
_controller = null
|
||||
|
||||
|
||||
# Check property config
|
||||
func _validate_property(property):
|
||||
if hand_offset_mode != 4 and (property.name == "position" or property.name == "rotation" or property.name == "scale" or property.name == "rotation_edit_mode" or property.name == "rotation_order"):
|
||||
# We control these, don't let the user set them.
|
||||
property.usage = PROPERTY_USAGE_NONE
|
||||
|
||||
|
||||
# This method verifies the hand has a valid configuration.
|
||||
func _get_configuration_warnings() -> PackedStringArray:
|
||||
var warnings := PackedStringArray()
|
||||
|
||||
# Check for XR Controller
|
||||
var controller = XRHelpers.get_xr_controller(self)
|
||||
if not controller:
|
||||
warnings.append("Hand should descent from an XRController3D node")
|
||||
|
||||
return warnings
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta):
|
||||
# If we have a controller, make sure our hand transform is updated when needed.
|
||||
if _controller:
|
||||
var tracker_and_pose = _controller.tracker + "." + _controller.pose
|
||||
if _controller_tracker_and_pose != tracker_and_pose:
|
||||
_controller_tracker_and_pose = tracker_and_pose
|
||||
if hand_offset_mode == 0:
|
||||
_update_transform()
|
||||
|
||||
|
||||
# Update our transform so we are positioned on our aim pose
|
||||
func _update_transform() -> void:
|
||||
if _apply_to and hand_offset_mode != 4:
|
||||
_apply_to.transform = XRTools.get_aim_offset(hand_offset_mode, _controller) * _base_transform
|
||||
1
addons/godot-xr-tools/hands/hand_aim_offset.gd.uid
Normal file
1
addons/godot-xr-tools/hands/hand_aim_offset.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bhjb6f4bslawl
|
||||
100
addons/godot-xr-tools/hands/hand_palm_offset.gd
Normal file
100
addons/godot-xr-tools/hands/hand_palm_offset.gd
Normal file
@@ -0,0 +1,100 @@
|
||||
@tool
|
||||
class_name XRToolsHandPalmOffset
|
||||
extends Node3D
|
||||
|
||||
## XRToolsHandPalmOffset will automatically adjust its position,
|
||||
## to locate the palm of a hand (within limits).
|
||||
|
||||
## Hand offset to apply based on our controller pose
|
||||
## You can use auto if you're using the default aim_pose or grip_pose poses.
|
||||
@export_enum("auto", "aim", "grip", "palm", "disable") var hand_offset_mode : int = 0:
|
||||
set(value):
|
||||
hand_offset_mode = value
|
||||
notify_property_list_changed()
|
||||
if is_inside_tree():
|
||||
_update_transform()
|
||||
|
||||
# Controller
|
||||
var _controller : XRController3D
|
||||
|
||||
# Keep track of our tracker and pose
|
||||
var _controller_tracker_and_pose : String = ""
|
||||
|
||||
# Which node are we applying our transform on?
|
||||
var _apply_to : Node3D
|
||||
|
||||
# Additional transform to apply
|
||||
var _base_transform : Transform3D = Transform3D()
|
||||
|
||||
## Add support for is_xr_class on XRTools classes
|
||||
func is_xr_class(xr_name: String) -> bool:
|
||||
return xr_name == "XRToolsHandAimOffset"
|
||||
|
||||
|
||||
## Set the node we apply our transform to
|
||||
## Must be set before _enter_tree is called for the first time.
|
||||
func set_apply_to(node : Node3D) -> void:
|
||||
_apply_to = node
|
||||
|
||||
|
||||
## Set a base transform to apply
|
||||
func set_base_transform(base_transform : Transform3D) -> void:
|
||||
_base_transform = base_transform
|
||||
if is_inside_tree():
|
||||
_update_transform()
|
||||
|
||||
|
||||
# Called when we're added to the tree
|
||||
func _enter_tree():
|
||||
if not _apply_to:
|
||||
_apply_to = self
|
||||
|
||||
_controller = XRHelpers.get_xr_controller(self)
|
||||
|
||||
_update_transform()
|
||||
|
||||
|
||||
# Called when we exit the tree
|
||||
func _exit_tree():
|
||||
if _controller:
|
||||
_controller = null
|
||||
|
||||
|
||||
# Check property config
|
||||
func _validate_property(property):
|
||||
if hand_offset_mode != 4 and (property.name == "position" or property.name == "rotation" or property.name == "scale" or property.name == "rotation_edit_mode" or property.name == "rotation_order"):
|
||||
# We control these, don't let the user set them.
|
||||
property.usage = PROPERTY_USAGE_NONE
|
||||
|
||||
|
||||
# This method verifies the hand has a valid configuration.
|
||||
func _get_configuration_warnings() -> PackedStringArray:
|
||||
var warnings := PackedStringArray()
|
||||
|
||||
# Check for XR Controller
|
||||
var controller = XRHelpers.get_xr_controller(self)
|
||||
if not controller:
|
||||
warnings.append("Hand should descent from an XRController3D node")
|
||||
elif controller.pose == "aim":
|
||||
# FIXME we don't get a refresh when the pose changes,
|
||||
# so this doesn't clear until a scene is reloaded...
|
||||
warnings.append("The aim pose is no longer suitable for hand position, consider using the grip pose instead")
|
||||
|
||||
return warnings
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta):
|
||||
# If we have a controller, make sure our hand transform is updated when needed.
|
||||
if _controller:
|
||||
var tracker_and_pose = _controller.tracker + "." + _controller.pose
|
||||
if _controller_tracker_and_pose != tracker_and_pose:
|
||||
_controller_tracker_and_pose = tracker_and_pose
|
||||
if hand_offset_mode == 0:
|
||||
_update_transform()
|
||||
|
||||
|
||||
# Update our transform so we are positioned on our palm
|
||||
func _update_transform() -> void:
|
||||
if _apply_to and hand_offset_mode != 4:
|
||||
_apply_to.transform = XRTools.get_palm_offset(hand_offset_mode, _controller) * _base_transform
|
||||
1
addons/godot-xr-tools/hands/hand_palm_offset.gd.uid
Normal file
1
addons/godot-xr-tools/hands/hand_palm_offset.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://drbnpanwky1vo
|
||||
154
addons/godot-xr-tools/hands/hand_physics_bone.gd
Normal file
154
addons/godot-xr-tools/hands/hand_physics_bone.gd
Normal file
@@ -0,0 +1,154 @@
|
||||
@tool
|
||||
class_name XRToolsHandPhysicsBone
|
||||
extends BoneAttachment3D
|
||||
|
||||
|
||||
## XR Tools Physics Hand Bone
|
||||
##
|
||||
## This script adds a physics-bone to a godot-xr-tools physics hand.
|
||||
##
|
||||
## It extends from [BoneAttachment3D] to track the position of the bone in
|
||||
## the hand skeleton, and uses this position to move a [CharacterBody3D]
|
||||
## physics-bone with a [CapsuleShape3D] collider.
|
||||
##
|
||||
## The physics-bone is manually driven with to the position and rotation of the
|
||||
## skeletal-bone. The physics-bone is set as top-level to prevent the
|
||||
## physics-bone from inheriting any hand scaling as this would scale the
|
||||
## collider which the physics engine cannot tolerate.
|
||||
##
|
||||
## To handle scaling, this script subscribes to the hand_scale_changed signal
|
||||
## emitted by the [XRToolsHand] script and manually adjusts the [CapsuleShape3D]
|
||||
## collider of the physics-bone to keep it sized appropriately.
|
||||
##
|
||||
## There are additional collision and group settings for this specific
|
||||
## bone, which allows per-bone collision detection.
|
||||
|
||||
|
||||
## Length of the physics-bone
|
||||
@export var length : float = 0.03
|
||||
|
||||
## Ratio of bone length to width
|
||||
@export var width_ratio : float = 0.3
|
||||
|
||||
## Additional collision layer for this one bone
|
||||
@export_flags_3d_physics var collision_layer : int = 0
|
||||
|
||||
## Additional bone group for this one bone
|
||||
@export var bone_group : String = ""
|
||||
|
||||
|
||||
# Physics-bone collider shape
|
||||
var _bone_shape : CapsuleShape3D
|
||||
|
||||
# Physics-bone body node
|
||||
var _physics_bone : CharacterBody3D
|
||||
|
||||
# Node attached to the skeletal-bone, and the target of the physics-bone
|
||||
var _skeletal_bone : Node3D
|
||||
|
||||
|
||||
# Add support for is_xr_class on XRTools classes
|
||||
func is_xr_class(xr_name: String) -> bool:
|
||||
return xr_name == "XRToolsHandPhysicsBone"
|
||||
|
||||
|
||||
# Called when the node enters the scene tree. This constructs the physics-bone
|
||||
# nodes and performs initial positioning.
|
||||
func _ready():
|
||||
# Skip if in the editor
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
||||
# Connect the 'hand_scale_changed' signal
|
||||
var physics_hand := XRToolsHand.find_instance(self) as XRToolsPhysicsHand
|
||||
if physics_hand:
|
||||
physics_hand.hand_scale_changed.connect(_on_hand_scale_changed)
|
||||
|
||||
# Construct the physics-bone shape
|
||||
_bone_shape = CapsuleShape3D.new()
|
||||
_bone_shape.margin = physics_hand.margin
|
||||
_on_hand_scale_changed(XRServer.world_scale)
|
||||
|
||||
# Construct the physics-bone collision shape
|
||||
var bone_collision := CollisionShape3D.new()
|
||||
bone_collision.set_name("BoneCollision")
|
||||
bone_collision.shape = _bone_shape
|
||||
#bone_collision.transform.basis = Basis(Vector3.RIGHT, PI/2)
|
||||
|
||||
# Construct the physics-bone body
|
||||
_physics_bone = CharacterBody3D.new()
|
||||
_physics_bone.set_name("BoneBody")
|
||||
_physics_bone.set_as_top_level(true)
|
||||
_physics_bone.collision_layer = physics_hand.collision_layer | collision_layer
|
||||
_physics_bone.collision_mask = 0
|
||||
_physics_bone.add_child(bone_collision)
|
||||
|
||||
# Set the optional bone group for all bones in the hand
|
||||
if not physics_hand.bone_group.is_empty():
|
||||
_physics_bone.add_to_group(physics_hand.bone_group)
|
||||
|
||||
# Set the optional bone group for this one bone
|
||||
if not bone_group.is_empty():
|
||||
_physics_bone.add_to_group(bone_group)
|
||||
|
||||
# Construct the bone middle spatial
|
||||
_skeletal_bone = Node3D.new()
|
||||
_skeletal_bone.transform.origin = Vector3.UP * length / 2
|
||||
|
||||
# Add the physics-bone body to this hand bone
|
||||
add_child(_physics_bone)
|
||||
add_child(_skeletal_bone)
|
||||
|
||||
# Perform initial teleport of the phsysics-bone to the skeletal-bone
|
||||
_teleport_bone()
|
||||
|
||||
|
||||
# Called during the physics process and moves the physics-bone to follow the
|
||||
# skeletal-bone.
|
||||
func _physics_process(delta: float) -> void:
|
||||
# Skip if in the editor
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
|
||||
_move_bone(delta)
|
||||
|
||||
|
||||
# This method moves the physics-bone to the skeletal-bone by first doing a
|
||||
# move_and_slide as this works well for collision-interactions. It then
|
||||
# rotates the physics-bone to match the skeletal-bone.
|
||||
func _move_bone(delta: float) -> void:
|
||||
# Get the skeletal-bone transform
|
||||
var bone_xform := _skeletal_bone.global_transform
|
||||
|
||||
# Get the required velocity to move the physics-bone to the skeletal-bone
|
||||
var bone_vel := (bone_xform.origin - _physics_bone.global_transform.origin) / delta
|
||||
|
||||
# Move the physics-bone into position
|
||||
_physics_bone.velocity = bone_vel
|
||||
_physics_bone.move_and_slide()
|
||||
|
||||
# Rotate the physics-bone into the correct rotation
|
||||
_physics_bone.global_transform.basis = bone_xform.basis
|
||||
|
||||
|
||||
# This method teleports the physics-bone to the skeletal-bone.
|
||||
func _teleport_bone() -> void:
|
||||
# Get the bone transform
|
||||
var bone_xform := _skeletal_bone.global_transform
|
||||
|
||||
# Set the bone position
|
||||
_physics_bone.global_transform = Transform3D(
|
||||
Basis(bone_xform.basis.get_rotation_quaternion()),
|
||||
bone_xform.origin)
|
||||
|
||||
|
||||
# This method handles changes to the hand scale by adjusting the
|
||||
# physics-bone collider shape to match.
|
||||
func _on_hand_scale_changed(scale: float) -> void:
|
||||
# Get the scaled length and width
|
||||
var length_scaled := length * scale
|
||||
var width_scaled := length_scaled * width_ratio
|
||||
|
||||
# Adjust the shape
|
||||
_bone_shape.radius = width_scaled
|
||||
_bone_shape.height = length_scaled
|
||||
1
addons/godot-xr-tools/hands/hand_physics_bone.gd.uid
Normal file
1
addons/godot-xr-tools/hands/hand_physics_bone.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bfo7c10rq6xuu
|
||||
8
addons/godot-xr-tools/hands/materials/african_hands.tres
Normal file
8
addons/godot-xr-tools/hands/materials/african_hands.tres
Normal file
@@ -0,0 +1,8 @@
|
||||
[gd_resource type="ORMMaterial3D" load_steps=3 format=3 uid="uid://bde1c58rcajee"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://cs7m7m0k2506g" path="res://addons/godot-xr-tools/hands/textures/african_baseColor.png" id="1_dn1i6"]
|
||||
[ext_resource type="Texture2D" uid="uid://h3sjbnu6uplb" path="res://addons/godot-xr-tools/hands/textures/hands_occlusionRoughnessMetallic.png" id="2_di2ux"]
|
||||
|
||||
[resource]
|
||||
albedo_texture = ExtResource("1_dn1i6")
|
||||
orm_texture = ExtResource("2_di2ux")
|
||||
@@ -0,0 +1,12 @@
|
||||
[gd_resource type="ORMMaterial3D" load_steps=4 format=3 uid="uid://26qy0lwlws4a"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://dk8o82rjww802" path="res://addons/godot-xr-tools/hands/textures/african_realistic_baseColor.png" id="1_seyus"]
|
||||
[ext_resource type="Texture2D" uid="uid://b6tgv6ucbgv3r" path="res://addons/godot-xr-tools/hands/textures/hands_normal.png" id="2_s3yd2"]
|
||||
[ext_resource type="Texture2D" uid="uid://h3sjbnu6uplb" path="res://addons/godot-xr-tools/hands/textures/hands_occlusionRoughnessMetallic.png" id="3_p3lxw"]
|
||||
|
||||
[resource]
|
||||
albedo_texture = ExtResource("1_seyus")
|
||||
orm_texture = ExtResource("3_p3lxw")
|
||||
normal_enabled = true
|
||||
normal_scale = 0.25
|
||||
normal_texture = ExtResource("2_s3yd2")
|
||||
@@ -0,0 +1,8 @@
|
||||
[gd_resource type="ORMMaterial3D" load_steps=3 format=3 uid="uid://dy6nhifvvmm73"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://c506svon268ms" path="res://addons/godot-xr-tools/hands/textures/caucasian_baseColor.png" id="1_si4on"]
|
||||
[ext_resource type="Texture2D" uid="uid://h3sjbnu6uplb" path="res://addons/godot-xr-tools/hands/textures/hands_occlusionRoughnessMetallic.png" id="2_agvfk"]
|
||||
|
||||
[resource]
|
||||
albedo_texture = ExtResource("1_si4on")
|
||||
orm_texture = ExtResource("2_agvfk")
|
||||
@@ -0,0 +1,12 @@
|
||||
[gd_resource type="ORMMaterial3D" load_steps=4 format=3 uid="uid://rwfrc1fdcjsj"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://n1xq4cm67o07" path="res://addons/godot-xr-tools/hands/textures/caucasian_realistic_baseColor.png" id="1_c8nm1"]
|
||||
[ext_resource type="Texture2D" uid="uid://b6tgv6ucbgv3r" path="res://addons/godot-xr-tools/hands/textures/hands_normal.png" id="2_ax2k6"]
|
||||
[ext_resource type="Texture2D" uid="uid://h3sjbnu6uplb" path="res://addons/godot-xr-tools/hands/textures/hands_occlusionRoughnessMetallic.png" id="3_6wg12"]
|
||||
|
||||
[resource]
|
||||
albedo_texture = ExtResource("1_c8nm1")
|
||||
orm_texture = ExtResource("3_6wg12")
|
||||
normal_enabled = true
|
||||
normal_scale = 0.25
|
||||
normal_texture = ExtResource("2_ax2k6")
|
||||
14
addons/godot-xr-tools/hands/materials/cleaning_glove.tres
Normal file
14
addons/godot-xr-tools/hands/materials/cleaning_glove.tres
Normal file
@@ -0,0 +1,14 @@
|
||||
[gd_resource type="ORMMaterial3D" load_steps=4 format=3 uid="uid://cdb40djkihelq"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://dv711ytktesj2" path="res://addons/godot-xr-tools/hands/textures/cleaning_glove_baseColor.png" id="1_k2x02"]
|
||||
[ext_resource type="Texture2D" uid="uid://dt6k4nuvpo38o" path="res://addons/godot-xr-tools/hands/textures/glove_normal.png" id="2_uiqlw"]
|
||||
[ext_resource type="Texture2D" uid="uid://yslwgnpbpeen" path="res://addons/godot-xr-tools/hands/textures/glove_occlusionRoughnessMetallic.png" id="3_8ux4v"]
|
||||
|
||||
[resource]
|
||||
albedo_texture = ExtResource("1_k2x02")
|
||||
orm_texture = ExtResource("3_8ux4v")
|
||||
normal_enabled = true
|
||||
normal_scale = 0.1
|
||||
normal_texture = ExtResource("2_uiqlw")
|
||||
clearcoat_enabled = true
|
||||
ao_light_affect = 1.0
|
||||
18
addons/godot-xr-tools/hands/materials/ghost_hand.tres
Normal file
18
addons/godot-xr-tools/hands/materials/ghost_hand.tres
Normal file
@@ -0,0 +1,18 @@
|
||||
[gd_resource type="StandardMaterial3D" load_steps=4 format=3 uid="uid://p0q2df2dmy62"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://dgkfppran5j1f" path="res://addons/godot-xr-tools/hands/textures/glove_caucasian_green_camo.png" id="1_rbe3r"]
|
||||
[ext_resource type="Texture2D" uid="uid://d2iocwfr47kqp" path="res://addons/godot-xr-tools/hands/textures/glove_fingerless_occlusionRoughnessMetallic.png" id="2_qqman"]
|
||||
|
||||
[sub_resource type="ORMMaterial3D" id="ORMMaterial3D_wu6j1"]
|
||||
transparency = 1
|
||||
depth_draw_mode = 1
|
||||
albedo_texture = ExtResource("1_rbe3r")
|
||||
orm_texture = ExtResource("2_qqman")
|
||||
|
||||
[resource]
|
||||
render_priority = -1
|
||||
next_pass = SubResource("ORMMaterial3D_wu6j1")
|
||||
transparency = 1
|
||||
no_depth_test = true
|
||||
shading_mode = 0
|
||||
albedo_color = Color(0, 1, 1, 0.25098)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user