Remove SpringBoneLogic & Vrm10InstanceSpringBone logics

This commit is contained in:
notargs 2021-10-05 18:49:08 +09:00
parent d185452f48
commit 46bc49a343
5 changed files with 3 additions and 313 deletions

View File

@ -1,201 +0,0 @@

using System;
using System.Collections.Generic;
using UnityEngine;
namespace UniVRM10
{
/// <summary>
///
/// original from
///
/// http://rocketjump.skr.jp/unity3d/109/
///
/// </summary>
public class SpringBoneLogic
{
Transform m_transform;
public Transform Head
{
get { return m_transform; }
}
public Vector3 Tail
{
get { return m_transform.localToWorldMatrix.MultiplyPoint(m_boneAxis * m_length); }
}
float m_length;
Vector3 m_currentTail;
Vector3 m_prevTail;
Vector3 m_localDir;
Quaternion m_localRotation;
public Quaternion LocalRotation
{
get { return m_localRotation; }
}
public Vector3 m_boneAxis;
public SpringBoneLogic(Transform center, Transform transform, Vector3 localChildPosition)
{
m_transform = transform;
var worldChildPosition = m_transform.TransformPoint(localChildPosition);
m_currentTail = center != null
? center.InverseTransformPoint(worldChildPosition)
: worldChildPosition
;
m_prevTail = m_currentTail;
m_localRotation = transform.localRotation;
m_boneAxis = localChildPosition.normalized;
m_length = localChildPosition.magnitude;
}
Quaternion ParentRotation
{
get
{
return m_transform.parent != null
? m_transform.parent.rotation
: Quaternion.identity
;
}
}
public struct InternalCollider
{
public VRM10SpringBoneColliderTypes ColliderTypes;
public Vector3 WorldPosition;
public float Radius;
public Vector3 WorldTail;
}
public void Update(Transform center,
float stiffnessForce, float dragForce, Vector3 external,
List<InternalCollider> colliders, float jointRadius)
{
var currentTail = center != null
? center.TransformPoint(m_currentTail)
: m_currentTail
;
var prevTail = center != null
? center.TransformPoint(m_prevTail)
: m_prevTail
;
// verlet積分で次の位置を計算
var nextTail = currentTail
+ (currentTail - prevTail) * (1.0f - dragForce) // 前フレームの移動を継続する(減衰もあるよ)
+ ParentRotation * m_localRotation * m_boneAxis * stiffnessForce // 親の回転による子ボーンの移動目標
+ external // 外力による移動量
;
// 長さをboneLengthに強制
nextTail = m_transform.position + (nextTail - m_transform.position).normalized * m_length;
// Collisionで移動
nextTail = Collision(colliders, nextTail, jointRadius);
m_prevTail = center != null
? center.InverseTransformPoint(currentTail)
: currentTail
;
m_currentTail = center != null
? center.InverseTransformPoint(nextTail)
: nextTail
;
//回転を適用
Head.rotation = ApplyRotation(nextTail);
}
protected virtual Quaternion ApplyRotation(Vector3 nextTail)
{
var rotation = ParentRotation * m_localRotation;
return Quaternion.FromToRotation(rotation * m_boneAxis,
nextTail - m_transform.position) * rotation;
}
bool TrySphereCollision(Vector3 worldPosition, float radius, ref Vector3 nextTail, float jointRadius)
{
var r = jointRadius + radius;
if (Vector3.SqrMagnitude(nextTail - worldPosition) <= (r * r))
{
// ヒット。Colliderの半径方向に押し出す
var normal = (nextTail - worldPosition).normalized;
var posFromCollider = worldPosition + normal * (jointRadius + radius);
// 長さをboneLengthに強制
nextTail = m_transform.position + (posFromCollider - m_transform.position).normalized * m_length;
return true;
}
else
{
return false;
}
}
bool TryCapsuleCollision(in InternalCollider collider, ref Vector3 nextTail, float jointRadius)
{
var P = collider.WorldTail - collider.WorldPosition;
var Q = m_transform.position - collider.WorldPosition;
var dot = Vector3.Dot(P, Q);
if (dot <= 0)
{
// head側半球の球判定
return TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail, jointRadius);
}
var t = dot / P.magnitude;
if (t >= 1.0f)
{
// tail側半球の球判定
return TrySphereCollision(collider.WorldTail, collider.Radius, ref nextTail, jointRadius);
}
// head-tail上の m_transform.position との最近点
var p = collider.WorldPosition + P * t;
return TrySphereCollision(p, collider.Radius, ref nextTail, jointRadius);
}
protected virtual Vector3 Collision(List<InternalCollider> colliders, Vector3 nextTail, float jointRadius)
{
foreach (var collider in colliders)
{
// すべての衝突判定を順番に実行する
switch (collider.ColliderTypes)
{
case VRM10SpringBoneColliderTypes.Sphere:
TrySphereCollision(collider.WorldPosition, collider.Radius, ref nextTail, jointRadius);
break;
case VRM10SpringBoneColliderTypes.Capsule:
TryCapsuleCollision(in collider, ref nextTail, jointRadius);
break;
default:
throw new NotImplementedException();
}
}
return nextTail;
}
public void DrawGizmo(Transform center, float radius, Color color)
{
var currentTail = center != null
? center.TransformPoint(m_currentTail)
: m_currentTail
;
var prevTail = center != null
? center.TransformPoint(m_prevTail)
: m_prevTail
;
Gizmos.color = Color.gray;
Gizmos.DrawLine(currentTail, prevTail);
Gizmos.DrawWireSphere(prevTail, radius);
Gizmos.color = color;
Gizmos.DrawLine(currentTail, m_transform.position);
Gizmos.DrawWireSphere(currentTail, radius);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: de6086bc4a9b4434b8cabc6e9e81eb4d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -28,22 +28,13 @@ namespace UniVRM10
[SerializeField, Range(0, 0.5f), Header("Collision")]
public float m_jointRadius = 0.02f;
SpringBoneLogic m_logic = null;
public void DrawGizmo(Transform center, Color color)
{
if (m_logic != null)
{
m_logic.DrawGizmo(center, m_jointRadius, color);
}
else
{
#if UNITY_EDITOR
// Gizmos.matrix = Transform.localToWorldMatrix;
Gizmos.color = color;
Gizmos.DrawSphere(transform.position, m_jointRadius);
// Gizmos.matrix = Transform.localToWorldMatrix;
Gizmos.color = color;
Gizmos.DrawSphere(transform.position, m_jointRadius);
#endif
}
}
}
}

View File

@ -104,11 +104,6 @@ namespace UniVRM10
constraint.Process();
}
//
// spring
//
//m_target.SpringBone.Process(m_target.SpringBoneCenter);
//
// gaze control
//

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace UniVRM10
@ -34,96 +33,13 @@ namespace UniVRM10
[SerializeField]
public List<VRM10SpringBoneJoint> Joints = new List<VRM10SpringBoneJoint>();
Transform m_center;
List<SpringBoneLogic.InternalCollider> m_colliderList;
List<(VRM10SpringBoneJoint, SpringBoneLogic)> m_logics;
public Spring(string name)
{
Name = name;
}
public void Process(Transform center)
{
m_center = center;
if (Joints == null)
{
return;
}
// gather colliders
if (m_colliderList == null)
{
m_colliderList = new List<SpringBoneLogic.InternalCollider>();
}
m_colliderList.Clear();
if (ColliderGroups != null)
{
foreach (var group in ColliderGroups.Where(x => x != null))
{
foreach (var collider in group.Colliders)
{
switch (collider.ColliderType)
{
case VRM10SpringBoneColliderTypes.Sphere:
m_colliderList.Add(new SpringBoneLogic.InternalCollider
{
ColliderTypes = VRM10SpringBoneColliderTypes.Sphere,
WorldPosition = collider.transform.TransformPoint(collider.Offset),
Radius = collider.Radius,
});
break;
case VRM10SpringBoneColliderTypes.Capsule:
m_colliderList.Add(new SpringBoneLogic.InternalCollider
{
ColliderTypes = VRM10SpringBoneColliderTypes.Capsule,
WorldPosition = collider.transform.TransformPoint(collider.Offset),
Radius = collider.Radius,
WorldTail = collider.transform.TransformPoint(collider.Tail)
});
break;
}
}
}
}
if (m_logics == null)
{
m_logics = Enumerable.Zip(Joints, Joints.Skip(1), (head, tail) =>
{
var localPosition = tail.transform.localPosition;
var scale = tail.transform.lossyScale;
var logic = new SpringBoneLogic(center, head.transform,
new Vector3(
localPosition.x * scale.x,
localPosition.y * scale.y,
localPosition.z * scale.z
));
return (head, logic);
}).ToList();
}
foreach (var (head, logic) in m_logics)
{
logic.Update(center,
head.m_stiffnessForce * Time.deltaTime,
head.m_dragForce,
head.m_gravityDir * (head.m_gravityPower * Time.deltaTime),
m_colliderList, head.m_jointRadius);
}
}
}
[SerializeField]
public List<Spring> Springs = new List<Spring>();
public void Process(Transform center)
{
foreach (var spring in Springs)
{
spring.Process(center);
}
}
}
}