Firstborn/Assets/Daz3D/Scripts/ClothCollisionAssigner.cs

155 lines
4.8 KiB
C#
Raw Normal View History

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using System;
public class ClothCollisionAssigner : MonoBehaviour
{
[Header("Paired Sphere Colliders")]
public SphereCollider[] m_UpperbodyColliders;
public SphereCollider[] m_LowerbodyColliders;
[Serializable]
public class ClothConfig
{
public Cloth m_ClothToManage;
public bool m_UpperBody;
public bool m_LowerBody;
}
[Header("Cloth Collision Assignments")]
public ClothConfig[] m_ClothConfigurationList;
private void addCollidersToCloth(SphereCollider[] collider_list, Cloth cloth_component)
{
int collider_size = 0;
foreach (SphereCollider sphere_collider in collider_list)
{
if (sphere_collider != null)
{
collider_size++;
}
}
if (collider_size % 2 != 0)
{
collider_size += 1;
}
int original_size = 0;
if (cloth_component.sphereColliders != null)
{
original_size = cloth_component.sphereColliders.Length;
}
ClothSphereColliderPair[] colliderpair_list = new ClothSphereColliderPair[original_size + (collider_size / 2)];
if (original_size > 0)
{
Array.Copy(cloth_component.sphereColliders, colliderpair_list, original_size);
}
for (int i = 0; i < collider_size / 2; i++)
{
colliderpair_list[original_size + i].first = collider_list[i * 2];
colliderpair_list[original_size + i].second = collider_list[i * 2 + 1];
}
cloth_component.sphereColliders = colliderpair_list;
}
public void addClothConfig(ClothConfig newConfig)
{
int new_size = m_ClothConfigurationList.Length + 1;
Array.Resize<ClothConfig>(ref m_ClothConfigurationList, new_size);
m_ClothConfigurationList[new_size - 1] = newConfig;
}
// merge cloth collision rig into rootnode of main figure rig
public void mergeRig(Transform destination_rootTransform)
{
Transform source_rootTransform = this.transform.Find("hip");
List<Transform> childTransform_stack = new List<Transform>();
childTransform_stack.Add(source_rootTransform);
while (childTransform_stack.Count > 0)
{
int next_Index = childTransform_stack.Count - 1;
Transform child = childTransform_stack[next_Index];
childTransform_stack.RemoveAt(next_Index);
if (child == null) continue;
// add all children to stack
for (int i = 0; i < child.childCount; i++)
{
Transform grandchild = child.GetChild(i);
if (grandchild != null)
childTransform_stack.Add(grandchild);
}
// check if child is a dforce collider
if (child.CompareTag("dForceCollider"))
{
// 1. unroll parent tree to get full path
Transform parent = child.parent;
String path_name = parent.name;
while (parent != null && parent.parent != source_rootTransform)
{
if (parent.parent == null) break;
parent = parent.parent;
path_name = parent.name + "/" + path_name;
}
// 2. find destination parent node
var dest_parent = destination_rootTransform.Find(path_name);
if (dest_parent != null)
{
// 3. move child to destination parent, worldspace = false
child.transform.SetParent(dest_parent, false);
}
}
}
}
public void ClearAllAssignments()
{
foreach (ClothConfig cloth_config in m_ClothConfigurationList)
{
if (cloth_config == null)
continue;
// delete existing cloth collisions
if (cloth_config.m_ClothToManage != null && cloth_config.m_ClothToManage.sphereColliders != null)
cloth_config.m_ClothToManage.sphereColliders = null;
}
}
public void AssignClothCollisionRigs()
{
foreach (ClothConfig cloth_config in m_ClothConfigurationList)
{
if (cloth_config == null)
continue;
if (cloth_config.m_UpperBody)
addCollidersToCloth(m_UpperbodyColliders, cloth_config.m_ClothToManage);
if (cloth_config.m_LowerBody)
addCollidersToCloth(m_LowerbodyColliders, cloth_config.m_ClothToManage);
}
}
// Start is called before the first frame update
void Start()
{
ClearAllAssignments();
AssignClothCollisionRigs();
}
// Update is called once per frame
void Update()
{
}
}