diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit.meta new file mode 100644 index 000000000..7185a9b0e --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b09ae318bccbfce4993fafb418e1e8c7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs new file mode 100644 index 000000000..d335044e3 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs @@ -0,0 +1,33 @@ +using Unity.Mathematics; + +namespace UniGLTF.SpringBoneJobs +{ + public static class AnglelimitCone + { + /// AngleLimit空間の方向ベクトル + /// radius + /// AngleLimit空間の方向ベクトル + public static float3 Apply(in float3 src, float angleLimit) + { + // tailDirのy要素をjointに設定されたangleの余弦と比較する + var cosAngle = math.cos(angleLimit); + if (src.y >= cosAngle) + { + return src; + } + + var tailDir = src; + { + // x・z要素を、tailDirの正弦とjointに設定されたangleの正弦の比を用いてスケールする + var ratio = math.sqrt((1.0f - cosAngle * cosAngle) / (1.0f - tailDir.y * tailDir.y)); + tailDir.x *= ratio; + tailDir.z *= ratio; + + // y要素を、jointに設定されたangleの余弦とする + tailDir.y = cosAngle; + } + + return src; + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs.meta new file mode 100644 index 000000000..ce8cc27a8 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitCone.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 780b79f298faea74ba4a123039a3faeb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs new file mode 100644 index 000000000..571984689 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs @@ -0,0 +1,32 @@ +using Unity.Mathematics; + +namespace UniGLTF.SpringBoneJobs +{ + public static class AnglelimitHinge + { + /// AngleLimit空間の方向ベクトル + /// radius + /// AngleLimit空間の方向ベクトル + public static float3 Apply(in float3 src, float limitAngle) + { + // x要素を0にし、正規化する + float3 tailDir = src; + tailDir.x = 0.0f; + tailDir = math.normalize(tailDir); + + // tailDirのy要素をjointに設定されたangleの余弦と比較する + var cosAngle = math.cos(limitAngle); + if (tailDir.y < cosAngle) + { + // z要素を、tailDirの正弦とjointに設定されたangleの正弦の比を用いてスケールする + var ratio = math.sqrt((1.0f - cosAngle * cosAngle) / (1.0f - tailDir.y * tailDir.y)); + tailDir.z *= ratio; + + // y要素を、jointに設定されたangleの余弦とする + tailDir.y = cosAngle; + } + + return tailDir; + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs.meta new file mode 100644 index 000000000..b385eae67 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitHinge.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bb1e1bbfc1a339c40b5df4d846f09da4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs new file mode 100644 index 000000000..1d9e06008 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs @@ -0,0 +1,36 @@ +using Unity.Mathematics; + +namespace UniGLTF.SpringBoneJobs +{ + public static class AnglelimitSpace + { + public static float3 ToTailDir(in quaternion src) + { + // // Y+方向からjointのheadからtailに向かうベクトルへの最小回転 + // let axisRotation = fromToQuaternion(vec3(0, 1, 0), boneAxis); + + // // limitのローカル空間をワールド空間に写像する回転 + // let rotation = + // joint.parent.worldRotation * + // joint.localSpaceInitialRotation * + // axisRotation * + // joint.limit.rotation; + + // // tailの向きをlimitのローカル空間に写像する + // tailDir = tailDir.applyQuaternion(rotation.inverse); + + // // limitを適用する + // joint.limit.apply(tailDir); + + // // tailの向きをワールド空間に戻す + // tailDir = tailDir.applyQuaternion(rotation); + + throw new System.NotImplementedException(); + } + + public static quaternion FromTailDir(in float3 src) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs.meta new file mode 100644 index 000000000..99e27a255 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpace.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e38e2998df511664cb0d6e582e6a05a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs new file mode 100644 index 000000000..e6d07be63 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs @@ -0,0 +1,36 @@ +using Unity.Mathematics; + +namespace UniGLTF.SpringBoneJobs +{ + public static class AnglelimitSpherical + { + /// AngleLimit空間の方向ベクトル + /// radius + /// radius + /// AngleLimit空間の方向ベクトル + public static float3 Apply(in float3 tailDir, float limitAnglePhi, float limitAngleTheta) + { + // tailDirのphi・thetaを計算する + var phi = math.atan2(tailDir.z, tailDir.y); + var theta = math.asin(tailDir.x); + + // phi・thetaをjointに設定されたphi・thetaを用いて制限する + // var isLimited = false; + if (math.abs(phi) > limitAnglePhi) + { + // isLimited = true; + phi = limitAnglePhi * math.sign(phi); + } + + // thetaをjointに設定されたthetaを用いて制限する + if (math.abs(theta) > limitAngleTheta) + { + // isLimited = true; + theta = limitAngleTheta * math.sign(theta); + } + + // tailDirをphi・thetaを用いて再計算する + return new float3(math.sin(theta), math.cos(theta) * math.cos(phi), math.cos(theta) * math.sin(phi)); + } + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs.meta new file mode 100644 index 000000000..c0439fd3e --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitSpherical.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc767b94391a0c44ebd21390c57a869e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs new file mode 100644 index 000000000..656ef327d --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs @@ -0,0 +1,11 @@ + +namespace UniGLTF.SpringBoneJobs +{ + public enum AnglelimitTypes + { + None, + Cone, + Hinge, + Spherical, + } +} \ No newline at end of file diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs.meta b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs.meta new file mode 100644 index 000000000..839768b66 --- /dev/null +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Anglelimit/AnglelimitTypes.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 56836f5a87c46a641a0ffc048c10655f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs index 96b48fa3a..d6566a659 100644 --- a/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs +++ b/Assets/UniGLTF/Runtime/SpringBoneJobs/Blittables/BlittableJointMutable.cs @@ -12,23 +12,48 @@ namespace UniGLTF.SpringBoneJobs.Blittables [Serializable] public readonly struct BlittableJointMutable { - private readonly float4x2 _data; - + /// + /// |x |y |z |w | + /// |--------|--------|--------|--------| + /// |stiff |g-power |drag |radius | + /// |g-dir.x |g-dir.y |g-dir.z | | + /// |al.type |limit1 |limit2 | + /// |offset.x|offset.y|offset.z|offset.w| + /// + /// g-power = gravityPower + /// g-dir = gravityDir + /// al = anglelimit + /// offset = anglelimitOffset + /// + private readonly float4x4 _data; + public float stiffnessForce => _data.c0.x; public float gravityPower => _data.c0.y; public float3 gravityDir => _data.c1.xyz; public float dragForce => _data.c0.z; public float radius => _data.c0.w; - + + public AnglelimitTypes anglelimitType => (AnglelimitTypes)_data.c2.x; + public float anglelimit1 => _data.c2.y; + public float anglelimit2 => _data.c2.z; + public quaternion anglelimitOffset => _data.c3.xyzw; + public BlittableJointMutable(float stiffnessForce = 0, float gravityPower = 0, float3 gravityDir = default, float dragForce = 0, - float radius = 0) + float radius = 0, + // anglelimit + float alType = 0, + float limit1 = 0, + float limit2 = 0, + quaternion offset = default) { var c0 = new float4(stiffnessForce, gravityPower, dragForce, radius); var c1 = new float4(gravityDir, 0); - _data = new float4x2(c0, c1); + var c2 = new float4(alType, limit1, limit2, 0); + var c3 = offset.value; + _data = new float4x4(c0, c1, c2, c3); } } } \ No newline at end of file