diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat.meta
index fda7b491..e6c78ccf 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Floor.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat.meta
index 4c66d558..3eca78b1 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Back.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat.meta
index fde3165e..b06b8c8e 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_Test_Front.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat
index 75309715..65b21dcd 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat
@@ -1,18 +1,5 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
---- !u!114 &-39192238385914524
-MonoBehaviour:
- m_ObjectHideFlags: 11
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 0}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
- m_Name:
- m_EditorClassIdentifier:
- version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -118,6 +105,19 @@ Material:
- _Tiling: {r: 1, g: 1, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
+--- !u!114 &3313520665792390858
+MonoBehaviour:
+ m_ObjectHideFlags: 11
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ version: 10
--- !u!114 &5537520944958903688
MonoBehaviour:
m_ObjectHideFlags: 11
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat.meta
index 02914d40..8a53ceee 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Materials/MC2_White.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat.meta
index ad27c0a4..8673df22 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Model/Materials/Arrow.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx.meta
index e459460c..375c71e4 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx.meta
@@ -95,3 +95,10 @@ ModelImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Model/arrow_b.fbx
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab.meta
index f1d57d96..f07ac579 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Cube.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab.meta
index 4edd2ca4..f3f30c31 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/CubeRoup.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab.meta
index 5aeb3b84..3250d247 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Env.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab.meta
index 999f1377..9eb703b9 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Plane.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab.meta
index 3c8b2c7a..650b1526 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeBuildDemo.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab.meta
index a3d21a79..13f1b0d1 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/RuntimeDressUpDemo.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab.meta
index 442d2814..02e3b3fd 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/SimpleImputManager.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab.meta
index e0caffd3..b4516368 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/Stage.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab.meta
index f2130bdc..08827b35 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_KAGURA.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab.meta
index 2ad5314b..de754a7c 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeBuild.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab.meta
index 028fcda0..861edc0c 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_RuntimeDressUp.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab.meta
index bca53a86..d30185ea 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/UI_Wind.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab.meta
index 24d6423d..d91442ed 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindDemo.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab.meta
index b0656b99..eeaa38c2 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Prefabs/WindParticle.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json.meta
index 04ed02d8..c065a153 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Resources/MC2_BoneCloth_Ribbon_Demo.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs
index 0c7539f8..48e2d326 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs
@@ -9,6 +9,13 @@ namespace MagicaCloth2
{
public Vector3 eulers = new Vector3(0, 90, 0);
public Space space = Space.World;
+ public enum UpdateMode
+ {
+ Update,
+ FixedUpdate,
+ }
+ [SerializeField]
+ private UpdateMode updateMode = UpdateMode.Update;
[SerializeField]
[Range(0.1f, 5.0f)]
@@ -19,11 +26,23 @@ namespace MagicaCloth2
private float time = 0;
+ private void FixedUpdate()
+ {
+ if (updateMode == UpdateMode.FixedUpdate)
+ UpdatePosition(Time.fixedDeltaTime);
+ }
+
void Update()
+ {
+ if (updateMode == UpdateMode.Update)
+ UpdatePosition(Time.deltaTime);
+ }
+
+ void UpdatePosition(float dtime)
{
if (useSin)
{
- time += Time.deltaTime;
+ time += dtime;
float ang = (time % interval) / interval * Mathf.PI * 2.0f;
var t = Mathf.Sin(ang);
if (space == Space.World)
@@ -33,7 +52,7 @@ namespace MagicaCloth2
}
else
{
- transform.Rotate(eulers * Time.deltaTime, space);
+ transform.Rotate(eulers * dtime, space);
}
}
}
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs.meta
index 25e7cb35..97968fcd 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs.meta
@@ -10,3 +10,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/AutoRotate.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs
index 0966cf7c..512d46ff 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs
@@ -124,10 +124,7 @@ namespace MagicaCloth2
return;
// カメラターゲットポジション
- if (cameraTarget)
- {
- cameraTargetPos = cameraTarget.position;
- }
+ cameraTargetPos = cameraTarget ? cameraTarget.position : transform.position;
// 補間
cameraDist = Mathf.SmoothDamp(cameraDist, setCameraDist, ref cameraDistVelocity, cameraDistHokanTime);
@@ -147,13 +144,13 @@ namespace MagicaCloth2
Vector3 pos = q * v;
// ターゲットポジション
- Vector3 tarpos = cameraTargetPos + cameraTargetOffset;
+ Vector3 tarpos = cameraTargetPos + transform.TransformVector(cameraTargetOffset);
Vector3 fixpos = tarpos + pos;
- cameraTransform.localPosition = fixpos;
+ cameraTransform.position = fixpos;
// 回転確定
Vector3 relativePos = tarpos - cameraTransform.position;
- Quaternion rot = Quaternion.LookRotation(relativePos);
+ Quaternion rot = Quaternion.LookRotation(relativePos, transform.up);
cameraTransform.rotation = rot;
}
@@ -182,8 +179,8 @@ namespace MagicaCloth2
}
else if (moveMode == MoveMode.Free)
{
- Vector3 offset = cameraTransform.up * -speed.y * moveSpeed;
- offset += cameraTransform.right * -speed.x * moveSpeed;
+ Vector3 offset = transform.InverseTransformDirection(cameraTransform.up) * -speed.y * moveSpeed;
+ offset += transform.InverseTransformDirection(cameraTransform.right) * -speed.x * moveSpeed;
cameraTargetOffset += offset;
}
@@ -207,7 +204,7 @@ namespace MagicaCloth2
///
private void OnTouchMove(int fid, Vector2 screenPos, Vector2 screenVelocity, Vector2 cmVelocity)
{
- screenVelocity *= Time.deltaTime * 60.0f;
+ screenVelocity *= SpeedAdjustment();
if (fid == 2)
{
@@ -225,6 +222,8 @@ namespace MagicaCloth2
private void OnDoubleTouchMove(int fid, Vector2 screenPos, Vector2 screenVelocity, Vector2 cmVelocity)
{
+ screenVelocity *= SpeedAdjustment();
+
if (SimpleInputManager.Instance.GetTouchCount() >= 3)
updateOffset(screenVelocity);
}
@@ -236,9 +235,15 @@ namespace MagicaCloth2
///
private void OnTouchPinch(float speedscr, float speedcm)
{
- //if (Mathf.Abs(speedcm) > 1.0f)
+ speedcm *= SpeedAdjustment();
+
if (SimpleInputManager.Instance.GetTouchCount() < 3)
updateZoom(speedcm);
}
+
+ private float SpeedAdjustment()
+ {
+ return Time.deltaTime * 60.0f;
+ }
}
}
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs.meta
index 469a81c6..99a01d8d 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CameraOrbit.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs.meta
index 2ab1f794..4b4ff663 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/CreateSingleton.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef.meta
index b7c84cab..fe02f634 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef.meta
@@ -5,3 +5,10 @@ AssemblyDefinitionImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/MagicaCloth2UPMImporterShaderGraph.asmdef
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs.meta
index 83d2a669..6d49f765 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/Editor/ShaderGraph/UnityPackageImporter.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs.meta
index 6425dc71..ba981ef0 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/GameObjectContainer.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef
new file mode 100644
index 00000000..f0713e7a
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef
@@ -0,0 +1,25 @@
+{
+ "name": "MagicaCloth2Example",
+ "rootNamespace": "",
+ "references": [
+ "MagicaClothV2",
+ "Unity.InputSystem"
+ ],
+ "includePlatforms": [],
+ "excludePlatforms": [],
+ "allowUnsafeCode": false,
+ "overrideReferences": true,
+ "precompiledReferences": [],
+ "autoReferenced": false,
+ "defineConstraints": [
+ "MAGICACLOTH2"
+ ],
+ "versionDefines": [
+ {
+ "name": "com.unity.inputsystem",
+ "expression": "1.0.0",
+ "define": "MC2_INPUTSYSTEM"
+ }
+ ],
+ "noEngineReferences": false
+}
\ No newline at end of file
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef.meta
new file mode 100644
index 00000000..cea1bdba
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: 5bc0ea054e216f5498d1a84885db7ab1
+AssemblyDefinitionImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/MagicaCloth2Example.asmdef
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs.meta
index 9a9f86f0..2027cc8d 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/ModelController.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs
index 1ed4f217..418d758c 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs
@@ -233,6 +233,7 @@ namespace MagicaCloth2
sdata.colliderCollisionConstraint.mode = ColliderCollisionConstraint.Mode.Point;
// setup collider
+ // UpperLeg L
var lobj = new GameObject("CapsuleCollider_L");
lobj.transform.SetParent(gameObjectContainer.GetGameObject("Character1_LeftUpLeg").transform);
lobj.transform.localPosition = new Vector3(0.0049f, 0.0f, -0.0832f);
@@ -240,17 +241,10 @@ namespace MagicaCloth2
var colliderL = lobj.AddComponent();
colliderL.direction = MagicaCapsuleCollider.Direction.Z;
colliderL.SetSize(0.082f, 0.094f, 0.3f);
-
- var robj = new GameObject("CapsuleCollider_R");
- robj.transform.SetParent(gameObjectContainer.GetGameObject("Character1_RightUpLeg").transform);
- robj.transform.localPosition = new Vector3(-0.0049f, 0.0f, -0.0832f);
- robj.transform.localEulerAngles = new Vector3(0.23f, -16.376f, -0.028f);
- var colliderR = robj.AddComponent();
- colliderR.direction = MagicaCapsuleCollider.Direction.Z;
- colliderR.SetSize(0.082f, 0.094f, 0.3f);
-
+ // UpperLeg R (Symmetry)
+ colliderL.symmetryMode = ColliderSymmetryMode.AutomaticHumanBody;
+ colliderL.UpdateParameters(); // Required when changing parameters.
sdata.colliderCollisionConstraint.colliderList.Add(colliderL);
- sdata.colliderCollisionConstraint.colliderList.Add(colliderR);
// start build
cloth.BuildAndRun();
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs.meta
index e13eec36..37b54f53 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeBuildDemo.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs.meta
index b83073fe..3b8111d3 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/RuntimeDressUpDemo.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs
new file mode 100644
index 00000000..ab3496ce
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs
@@ -0,0 +1,196 @@
+// Magica Cloth 2.
+// Copyright (c) 2025 MagicaSoft.
+// https://magicasoft.jp
+using UnityEngine;
+#if MC2_INPUTSYSTEM
+using UnityEngine.InputSystem;
+using UnityEngine.InputSystem.EnhancedTouch;
+#endif
+
+namespace MagicaCloth2
+{
+ ///
+ /// InputManager/InputSystem入力切り替えラッパー
+ ///
+ public class SimpleInput
+ {
+#if MC2_INPUTSYSTEM
+ // (New) Imput System
+ public static void Init()
+ {
+ EnhancedTouchSupport.Enable();
+ }
+
+ public static int touchCount
+ {
+ get
+ {
+ return UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches.Count;
+ }
+ }
+
+ public static UnityEngine.Touch GetTouch(int index)
+ {
+ var touchData = new UnityEngine.Touch();
+
+ int count = UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches.Count;
+ if (index < count)
+ {
+ var touch = UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches[index];
+
+ // convert
+ touchData.fingerId = touch.finger.index;
+ touchData.position = touch.screenPosition;
+ touchData.deltaPosition = touch.delta;
+ switch (touch.phase)
+ {
+ case UnityEngine.InputSystem.TouchPhase.Canceled:
+ touchData.phase = UnityEngine.TouchPhase.Canceled;
+ break;
+ case UnityEngine.InputSystem.TouchPhase.Ended:
+ touchData.phase = UnityEngine.TouchPhase.Ended;
+ break;
+ case UnityEngine.InputSystem.TouchPhase.Moved:
+ touchData.phase = UnityEngine.TouchPhase.Moved;
+ break;
+ case UnityEngine.InputSystem.TouchPhase.Began:
+ touchData.phase = UnityEngine.TouchPhase.Began;
+ break;
+ }
+ }
+
+ return touchData;
+ }
+
+ public static bool GetKey(KeyCode key)
+ {
+ switch (key)
+ {
+ case KeyCode.Escape:
+ return Keyboard.current.escapeKey.isPressed;
+ default:
+ return false;
+ }
+ }
+
+ public static bool GetKeyDown(KeyCode key)
+ {
+ switch (key)
+ {
+ case KeyCode.Backspace:
+ return Keyboard.current.backspaceKey.wasPressedThisFrame;
+ default:
+ return false;
+ }
+ }
+
+ public static bool GetMouseButtonDown(int button)
+ {
+ switch (button)
+ {
+ case 0:
+ return Mouse.current.leftButton.wasPressedThisFrame;
+ case 1:
+ return Mouse.current.rightButton.wasPressedThisFrame;
+ case 2:
+ return Mouse.current.middleButton.wasPressedThisFrame;
+ default:
+ return false;
+ }
+ }
+
+ public static bool GetMouseButtonUp(int button)
+ {
+ switch (button)
+ {
+ case 0:
+ return Mouse.current.leftButton.wasReleasedThisFrame;
+ case 1:
+ return Mouse.current.rightButton.wasReleasedThisFrame;
+ case 2:
+ return Mouse.current.middleButton.wasReleasedThisFrame;
+ default:
+ return false;
+ }
+ }
+
+ public static Vector3 mousePosition
+ {
+ get
+ {
+ return Mouse.current.position.ReadValue();
+ }
+ }
+
+ public static float GetMouseScrollWheel()
+ {
+ // 古いInputSystemに不具合あり
+ // ホイールデルタがデフォルトでx120されて返ってくる
+ // これはWindowsのみの挙動でMac/Linuxでは発生しない
+ // そしてUnity 2023.2以降は修正された
+
+ float value = Mouse.current.scroll.ReadValue().y * 0.12f; // base
+#if UNITY_2023_2_OR_NEWER
+ return value;
+#else
+#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
+ return value / 120.0f; // ホイールデルタの不具合を吸収
+#else
+ return value;
+#endif
+#endif
+ }
+#else
+ // (Old) Imput Manager
+ public static void Init()
+ {
+ }
+
+ public static int touchCount
+ {
+ get
+ {
+ return Input.touchCount;
+ }
+ }
+
+ public static Touch GetTouch(int index)
+ {
+ return Input.GetTouch(index);
+ }
+
+ public static bool GetKey(KeyCode key)
+ {
+ return Input.GetKey(key);
+ }
+
+ public static bool GetKeyDown(KeyCode key)
+ {
+ return Input.GetKeyDown(key);
+ }
+
+ public static bool GetMouseButtonDown(int button)
+ {
+ return Input.GetMouseButtonDown(button);
+ }
+
+ public static bool GetMouseButtonUp(int button)
+ {
+ return Input.GetMouseButtonUp(button);
+ }
+
+ public static Vector3 mousePosition
+ {
+ get
+ {
+ return Input.mousePosition;
+ }
+ }
+
+ public static float GetMouseScrollWheel()
+ {
+ return Input.GetAxis("Mouse ScrollWheel");
+ }
+#endif
+ }
+}
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs.meta
new file mode 100644
index 00000000..45af9716
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs.meta
@@ -0,0 +1,18 @@
+fileFormatVersion: 2
+guid: ab72fcfec8965ae4181307a06400b57b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInput.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs
index 0a3b4405..bf5a66c2 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs
@@ -105,6 +105,8 @@ namespace MagicaCloth2
//=========================================================================================
protected override void InitSingleton()
{
+ SimpleInput.Init();
+
// スクリーン情報
CalcScreenDpi();
@@ -188,7 +190,7 @@ namespace MagicaCloth2
public int GetTouchCount()
{
- return Input.touchCount;
+ return SimpleInput.touchCount;
}
public bool IsUI()
@@ -199,7 +201,7 @@ namespace MagicaCloth2
if (mobilePlatform)
{
// モバイル用タッチ入力
- return EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId);
+ return EventSystem.current.IsPointerOverGameObject(SimpleInput.GetTouch(0).fingerId);
}
else
{
@@ -214,7 +216,7 @@ namespace MagicaCloth2
///
private void UpdateMobile()
{
- int count = Input.touchCount;
+ int count = SimpleInput.touchCount;
if (count == 0)
{
@@ -223,7 +225,7 @@ namespace MagicaCloth2
// バックボタン
if (Application.platform == RuntimePlatform.Android)
{
- if (Input.GetKey(KeyCode.Escape) && lastTime + 0.2f < Time.time)
+ if (SimpleInput.GetKey(KeyCode.Escape) && lastTime + 0.2f < Time.time)
{
lastTime = Time.time;
if (OnBackButton != null)
@@ -239,7 +241,7 @@ namespace MagicaCloth2
// メイン
for (int i = 0; i < count; i++)
{
- Touch touch = Input.GetTouch(i);
+ Touch touch = SimpleInput.GetTouch(i);
int fid = touch.fingerId;
// フィンガーIDが0と1以外は無視する
@@ -289,7 +291,7 @@ namespace MagicaCloth2
int setcnt = 0;
for (int j = 0; j < count; j++)
{
- Touch t = Input.GetTouch(j);
+ Touch t = SimpleInput.GetTouch(j);
if (mainFingerId == t.fingerId)
{
t1pos = t.position;
@@ -497,7 +499,7 @@ namespace MagicaCloth2
private void UpdateMouse()
{
// BackSpace を Android 端末のバックボタンに割り当てる
- if (Input.GetKeyDown(KeyCode.Backspace))
+ if (SimpleInput.GetKeyDown(KeyCode.Backspace))
{
if (OnBackButton != null)
OnBackButton();
@@ -507,7 +509,7 @@ namespace MagicaCloth2
for (int i = 0; i < 3; i++)
{
// マウスボタンダウン
- if (Input.GetMouseButtonDown(i))
+ if (SimpleInput.GetMouseButtonDown(i))
{
if (IsUI())
continue;
@@ -519,46 +521,46 @@ namespace MagicaCloth2
mouseDown[i] = true;
// 入力位置を記録
- downPos[i] = Input.mousePosition;
- mouseOldMovePos[i] = Input.mousePosition;
+ downPos[i] = SimpleInput.mousePosition;
+ mouseOldMovePos[i] = SimpleInput.mousePosition;
if (i == 0)
- flickDownPos[i] = Input.mousePosition;
+ flickDownPos[i] = SimpleInput.mousePosition;
// タッチダウンイベント発行
if (OnTouchDown != null)
- OnTouchDown(i, Input.mousePosition);
+ OnTouchDown(i, SimpleInput.mousePosition);
}
// マウスボタンアップ
- if (Input.GetMouseButtonUp(i) && mouseDown[i])
+ if (SimpleInput.GetMouseButtonUp(i) && mouseDown[i])
{
mouseDown[i] = false;
// フリック判定
if (i == 0)
{
- CheckFlic(i, mouseOldMovePos[i], Input.mousePosition, flickDownPos[i], flickDownTime[i]);
+ CheckFlic(i, mouseOldMovePos[i], SimpleInput.mousePosition, flickDownPos[i], flickDownTime[i]);
}
mouseOldMovePos[i] = Vector2.zero;
// タッチアップイベント
if (OnTouchUp != null)
- OnTouchUp(i, Input.mousePosition);
+ OnTouchUp(i, SimpleInput.mousePosition);
// タップ判定
- float distcm = Vector2.Distance(downPos[0], Input.mousePosition) / screenDpc;
+ float distcm = Vector2.Distance(downPos[0], SimpleInput.mousePosition) / screenDpc;
if (distcm <= tapRadiusCm)
{
if (OnTouchTap != null)
- OnTouchTap(i, Input.mousePosition);
+ OnTouchTap(i, SimpleInput.mousePosition);
}
}
// 移動
if (mouseDown[i])
{
- Vector2 spos = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
+ Vector2 spos = new Vector2(SimpleInput.mousePosition.x, SimpleInput.mousePosition.y);
Vector2 delta = spos - mouseOldMovePos[i];
if (spos != mouseOldMovePos[i])
@@ -569,10 +571,10 @@ namespace MagicaCloth2
// 移動通知(現在スクリーン座標、速度(スクリーン比率/s)、速度(cm/s))
if (OnTouchMove != null)
- OnTouchMove(i, Input.mousePosition, CalcScreenRatioVector(delta) / Time.deltaTime, speedcm);
+ OnTouchMove(i, SimpleInput.mousePosition, CalcScreenRatioVector(delta) / Time.deltaTime, speedcm);
}
- mouseOldMovePos[i] = Input.mousePosition;
+ mouseOldMovePos[i] = SimpleInput.mousePosition;
// フリックダウン位置更新
flickDownPos[i] = (flickDownPos[i] + spos) * 0.5f;
@@ -582,7 +584,7 @@ namespace MagicaCloth2
}
// ピンチイン/アウト
- float w = Input.GetAxis("Mouse ScrollWheel");
+ float w = SimpleInput.GetMouseScrollWheel();
if (Mathf.Abs(w) > 0.01f)
{
// モバイル入力とスケール感を合わせるために係数を掛ける
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs.meta
index caaf8f95..27ceaaed 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SimpleInputManager.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs.meta
index 5b845c36..50f57feb 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/SliderText.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs.meta
index 1a6c0764..f8b8c699 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/TargetFPS.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs.meta
index 4892d391..8bfef270 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Scripts/WindDemo.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph.meta
index b9c5388b..344ba09e 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph.meta
@@ -8,3 +8,10 @@ ScriptedImporter:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Back.shadergraph
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph.meta
index ff256694..15a92363 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph.meta
@@ -8,3 +8,10 @@ ScriptedImporter:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3}
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Shaders/MC2_Common_Lit_Front.shadergraph
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png.meta
index 9664902f..008b57bd 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png.meta
@@ -133,3 +133,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/Common/Textures/SD_UnityChan_Skirt_PaintMap.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity.meta
index 08041a60..18e2feb8 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeBuild_CoreRP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity.meta
index 9c7cb142..5f4d8e54 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/RuntimeDressUp_CoreRP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity
index 45a9369b..78a5aa64 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b0a30028efec38943b8b0a0a3e6c27faf3b27c037688c241e17d2a10cfc19731
-size 23432
+oid sha256:6fe3dc5720a8c5fad181a0d26496c40a37ac6d36d4adaa54682a75eaf87a33c9
+size 22305
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity.meta
index 8d3ddf15..47ff0707 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/UnityChanKAGURA_CoreRP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity.meta
index 1bb3c959..584dc04f 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/CoreRP/Wind_CoreRP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset.meta
index a30f1354..0009e1cc 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/MC2_SkyandFogSettingsProfile.asset
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity.meta
index fd609d8a..559bca0a 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeBuild_HDRP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity.meta
index 8bea2cf0..4cd66521 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/RuntimeDressUp_HDRP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity.meta
index 374b61f5..d9390fcf 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/UnityChanKAGURA_HDRP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity.meta
index b627f60c..b0a5099b 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/HDRP/Wind_HDRP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity.meta
index 632a5982..9ec4fc44 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeBuild_URP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity.meta
index 6dcb7c2b..d0acf47c 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/RuntimeDressUp_URP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity.meta
index c50bf39e..15520817 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/UnityChanKAGURA_URP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity.meta
index cb67e264..f298694a 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity.meta
@@ -5,3 +5,10 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes/URP/Wind_URP.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher.meta
new file mode 100644
index 00000000..74824a62
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 20f694a56cb3ba842b35402189c3b2f6
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D.meta
new file mode 100644
index 00000000..a52c053f
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 098d9df8397d80f45baed0214420d1cf
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity
new file mode 100644
index 00000000..3f6cc57d
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1344538bb448c3f15d0aa4c3ccf0527dbe7cea8b115f959fecdb099f9e40c58d
+size 35742
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity.meta
new file mode 100644
index 00000000..ff590357
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: 8a0637df5c1ee8a4d8d6c5d2f3807cde
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeBuild_HighDefinition3D.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity
new file mode 100644
index 00000000..c23bafbe
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:425ee3749faad5217ec23076fe0ec0a8dba02c1e24e64d425f87cab0e1d4ced3
+size 38769
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity.meta
new file mode 100644
index 00000000..e0f9bca4
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: 30700d501f109174891f340ae1fc1833
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/RuntimeDressUp_HighDefinition3D.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity
new file mode 100644
index 00000000..71564526
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:73cb2e8ccc8c4db1d827759ef27c59305c8e40160b46a3788ae65706ba821f0c
+size 35263
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity.meta
new file mode 100644
index 00000000..08312189
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: ca2d4f8e19e54d642bbc386701570fd4
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/UnityChanKAGURA_HighDefinition3D.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity
new file mode 100644
index 00000000..244111f0
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7aea3460aabbbee2de0bcb7b926a64e0187975a7e24f265bb57a57252d86e30b
+size 44593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity.meta
new file mode 100644
index 00000000..0d3360fe
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: 8ef5d38bbe84ef44cb76386cf579b78d
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/HighDefinition3D/Wind_HighDefinition3D.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D.meta
new file mode 100644
index 00000000..c51f6ec4
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ee41de38686ef9b439643dd695fd9f9d
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity
new file mode 100644
index 00000000..6571ff92
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cb85169ab67c2f674187b692f0efe495f7ee2f6f2723132ddec09dc0e6d60fde
+size 27478
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity.meta
new file mode 100644
index 00000000..75bcbb9a
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: 9d96bb6c1a7bbf14b95fba198bd36558
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeBuild_Universal3D.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity
new file mode 100644
index 00000000..18f566a9
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bfc77efbc86c3ba7859690d352fb5b0a81febd4dc8f30d38846819e0d4c6d74a
+size 30517
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity.meta
new file mode 100644
index 00000000..0a6c8542
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: 01f984873de94d845a6f0dad6e1764ce
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/RuntimeDressUp_Universal3D.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity
new file mode 100644
index 00000000..c9715c26
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bf136fcfed91b4bf1b09194afdbda5cf3446527584d73ea128f0b86fb8bec9b9
+size 23282
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity.meta
new file mode 100644
index 00000000..b892e855
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: 54b38eb7d538c7f44b7fd7a9df0478d3
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/UnityChanKAGURA_Universal3D.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity
new file mode 100644
index 00000000..e0bd9e1b
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d36cd32becfcb97c511df00aa9e6f2c9b43a908600d68ffc4de28505eaf19b05
+size 34225
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity.meta
new file mode 100644
index 00000000..405c8dc2
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: 44a8005bc0be2894fb5f7cec86f3eeae
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/DemoScenes_Unity_6.1_or_Higher/Universal3D/Wind_Universal3D.unity
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png.meta
index a91419f5..a9e64089 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png.meta
@@ -133,3 +133,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/Logo/Dark_Silhouette.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat
index c1138f16..52d1b9fa 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat
@@ -1,6 +1,6 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
---- !u!114 &-5805247609134839791
+--- !u!114 &-8367319535634762937
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat.meta
index 1df11100..374da6eb 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_def_mat.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat
index 0dc73c45..5dbb1be2 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat
@@ -105,19 +105,6 @@ Material:
- _Tiling: {r: 1, g: 1, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
---- !u!114 &1416824612331664537
-MonoBehaviour:
- m_ObjectHideFlags: 11
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 0}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
- m_Name:
- m_EditorClassIdentifier:
- version: 10
--- !u!114 &5988364977265673585
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -131,3 +118,16 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
version: 0
+--- !u!114 &6642007414726601541
+MonoBehaviour:
+ m_ObjectHideFlags: 11
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ version: 10
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat.meta
index 8acd3aac..48e00d42 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_nol_mat.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat
index 7ca1a6ee..487cbc5b 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat
@@ -13,6 +13,19 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
version: 0
+--- !u!114 &-3527211999276890483
+MonoBehaviour:
+ m_ObjectHideFlags: 11
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -118,16 +131,3 @@ Material:
- _Tiling: {r: 1, g: 1, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
---- !u!114 &7561439969631927331
-MonoBehaviour:
- m_ObjectHideFlags: 11
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 0}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
- m_Name:
- m_EditorClassIdentifier:
- version: 10
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat.meta
index a77823f1..8015b067 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/SB_skin_mat.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat
index 8b14002c..9b400892 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat
@@ -1,18 +1,5 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
---- !u!114 &-3348263818793008538
-MonoBehaviour:
- m_ObjectHideFlags: 11
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 0}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
- m_Name:
- m_EditorClassIdentifier:
- version: 10
--- !u!114 &-1839986918002453301
MonoBehaviour:
m_ObjectHideFlags: 11
@@ -26,6 +13,19 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
version: 0
+--- !u!114 &-1156612615677998621
+MonoBehaviour:
+ m_ObjectHideFlags: 11
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat.meta
index 39800a06..24f6d5f2 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/def_mat.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat
index 48b84cb1..b2a9d855 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat
@@ -118,7 +118,7 @@ Material:
- _Tiling: {r: 1, g: 1, b: 0, a: 0}
m_BuildTextureStacks: []
m_AllowLocking: 1
---- !u!114 &8904441550551059416
+--- !u!114 &3524422830314133294
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat.meta
index 1adcd0bb..8cad7460 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/hair_mat.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat
index 59044bee..e12c6539 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat
@@ -1,5 +1,18 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &-4586411623184738822
+MonoBehaviour:
+ m_ObjectHideFlags: 11
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ version: 10
--- !u!21 &2100000
Material:
serializedVersion: 8
@@ -118,16 +131,3 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
version: 0
---- !u!114 &6747972257908541556
-MonoBehaviour:
- m_ObjectHideFlags: 11
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 0}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3}
- m_Name:
- m_EditorClassIdentifier:
- version: 10
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat.meta
index 9da46773..0f0c6611 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/mouth_mat.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat
index 26dd958b..46d08385 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat
@@ -1,6 +1,6 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
---- !u!114 &-3882220622740168363
+--- !u!114 &-1182480219143839893
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat.meta
index e55fc721..9d078a31 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/nol_mat.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat
index c4dc4bab..7ad20da8 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat
@@ -1,6 +1,6 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
---- !u!114 &-6659663828051372056
+--- !u!114 &-6487248340714685668
MonoBehaviour:
m_ObjectHideFlags: 11
m_CorrespondingSourceObject: {fileID: 0}
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat.meta
index 2727e440..15148879 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Materials/skin_mat.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller.meta
index 78613b00..7b18d809 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/SD_UnityChan.controller
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png.meta
index e2bfad8d..f9ed6109 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png.meta
@@ -133,3 +133,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_sum.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png.meta
index 878450c3..b9f51e6a 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png.meta
@@ -133,3 +133,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/body_win.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png.meta
index b50338c6..6d783611 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png.meta
@@ -133,3 +133,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/misaki_head.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png.meta
index 63b7e687..fc88cc45 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png.meta
@@ -133,3 +133,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/utc_all2.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png.meta
index c3cf7c14..fae0a2a9 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png.meta
@@ -133,3 +133,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Textures/yuko_head.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab
index df73543c..2e175432 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e36810faeafb1c9effaf360ca0d250e8fd737558fcc4423ca3f84f8acf859686
-size 194332
+oid sha256:65425706988a58d5797e6383be3c3c3f073e26decefa6e16acd3474a16477045
+size 230271
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab.meta
index d102802d..5edf25b8 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Body).prefab.meta
@@ -5,3 +5,11 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid
+ (Body).prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab
index 07235922..7f8d6581 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:8404f84ad997715570beb3ab06d2fe48412b78df0cd38f68aab944574e1ce137
-size 152902
+oid sha256:f1d1e9c1b01e53284c9e76f151987e27c12bd36e7fcadb114ea5b7b69a379bd4
+size 185523
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab.meta
index f8b4e144..81c1dbd2 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Hair).prefab.meta
@@ -5,3 +5,11 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid
+ (Hair).prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Skeleton).prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Skeleton).prefab.meta
index e2be6b5d..e73b56ac 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Skeleton).prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid (Skeleton).prefab.meta
@@ -5,3 +5,11 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid
+ (Skeleton).prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid Variant.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid Variant.prefab.meta
index aa0274ac..0a9fddf7 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid Variant.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid Variant.prefab.meta
@@ -5,3 +5,11 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid
+ Variant.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx.meta
index a8e69415..6959d13c 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx.meta
@@ -524,7 +524,8 @@ ModelImporter:
- name: Character1_LeftHandPinky3
parentName: Character1_LeftHandPinky2
position: {x: -0.0075915335, y: -0.000000009536743, z: 0}
- rotation: {x: -0.000000002793968, y: -0.000000029802322, z: -0.000000007450581, w: 1}
+ rotation: {x: -0.000000002793968, y: -0.000000029802322, z: -0.000000007450581,
+ w: 1}
scale: {x: 0.9999999, y: 1, z: 0.99999994}
- name: Character1_LeftHandIndex1
parentName: Character1_LeftHand
@@ -539,7 +540,8 @@ ModelImporter:
- name: Character1_LeftHandIndex3
parentName: Character1_LeftHandIndex2
position: {x: -0.0107357595, y: 0.000000014305114, z: -0.000000076293944}
- rotation: {x: -0.0000000018626456, y: -0.00000014901154, z: -0.0000000037252887, w: 1}
+ rotation: {x: -0.0000000018626456, y: -0.00000014901154, z: -0.0000000037252887,
+ w: 1}
scale: {x: 1.0000004, y: 0.9999999, z: 1.0000004}
- name: Character1_LeftHandThumb1
parentName: Character1_LeftHand
@@ -559,7 +561,8 @@ ModelImporter:
- name: Character1_LeftHandThumb4
parentName: Character1_LeftHandThumb3
position: {x: -0.012429466, y: -0.000000038146972, z: 0.000000038146972}
- rotation: {x: 0.00000014156107, y: 0.00000002607702, z: -0.000000089406974, w: 1}
+ rotation: {x: 0.00000014156107, y: 0.00000002607702, z: -0.000000089406974,
+ w: 1}
scale: {x: 1.0000001, y: 0.99999946, z: 0.9999998}
- name: Character1_LeftHandMiddle1
parentName: Character1_LeftHand
@@ -574,7 +577,8 @@ ModelImporter:
- name: Character1_LeftHandMiddle3
parentName: Character1_LeftHandMiddle2
position: {x: -0.012807655, y: -0.000000005960464, z: -0.000000076293944}
- rotation: {x: 0.000000007450579, y: -0.000000014901163, z: -0.0000000037252907, w: 1}
+ rotation: {x: 0.000000007450579, y: -0.000000014901163, z: -0.0000000037252907,
+ w: 1}
scale: {x: 1, y: 1.0000001, z: 0.99999994}
- name: J_L_Elbow
parentName: Character1_LeftForeArm
@@ -619,17 +623,20 @@ ModelImporter:
- name: J_L_HairTail_01
parentName: J_L_HairTail_00
position: {x: 0.000000019073486, y: -0.000000076293944, z: -0.19820912}
- rotation: {x: 0.000000029802326, y: -0.000000022351744, z: 0.000000011175873, w: 1}
+ rotation: {x: 0.000000029802326, y: -0.000000022351744, z: 0.000000011175873,
+ w: 1}
scale: {x: 1, y: 0.99999994, z: 1.0000001}
- name: J_L_HairTail_02
parentName: J_L_HairTail_01
position: {x: -0, y: 0.000000114440915, z: -0.2224917}
- rotation: {x: -4.9960047e-16, y: -0.00000006705523, z: -0.0000000074505815, w: 1}
+ rotation: {x: -4.9960047e-16, y: -0.00000006705523, z: -0.0000000074505815,
+ w: 1}
scale: {x: 0.9999999, y: 1.0000002, z: 0.99999994}
- name: J_L_HairTail_03
parentName: J_L_HairTail_02
position: {x: 0.000000019073486, y: 0.000000076293944, z: -0.17191942}
- rotation: {x: 0.000000014901161, y: -0.000000007450581, z: -0.000000007450581, w: 1}
+ rotation: {x: 0.000000014901161, y: -0.000000007450581, z: -0.000000007450581,
+ w: 1}
scale: {x: 1, y: 1, z: 1}
- name: J_L_HeadRibbon_00
parentName: Character1_Head
@@ -649,7 +656,8 @@ ModelImporter:
- name: J_L_HeadRibbon_03
parentName: J_L_HeadRibbon_02
position: {x: -0.000000076293944, y: -0.00000015258789, z: 0.16675673}
- rotation: {x: -0.00000022351746, y: -0.00000011920929, z: 0.0000000149011345, w: 1}
+ rotation: {x: -0.00000022351746, y: -0.00000011920929, z: 0.0000000149011345,
+ w: 1}
scale: {x: 1, y: 0.9999999, z: 1.0000001}
- name: J_R_HairSide2_00
parentName: Character1_Head
@@ -669,17 +677,20 @@ ModelImporter:
- name: J_R_HairTail_01
parentName: J_R_HairTail_00
position: {x: -0.000000095367426, y: 0.0000009918213, z: -0.19820796}
- rotation: {x: 0.000000029802322, y: -0.0000000074505815, z: -0.00000010058282, w: 1}
+ rotation: {x: 0.000000029802322, y: -0.0000000074505815, z: -0.00000010058282,
+ w: 1}
scale: {x: 1.0000001, y: 0.99999994, z: 1}
- name: J_R_HairTail_02
parentName: J_R_HairTail_01
position: {x: -0.0000004196167, y: -0.0000005340576, z: -0.2224927}
- rotation: {x: 0.000000089406925, y: 0.000000014901161, z: -0.000000040978207, w: 1}
+ rotation: {x: 0.000000089406925, y: 0.000000014901161, z: -0.000000040978207,
+ w: 1}
scale: {x: 0.99999964, y: 1.0000002, z: 1}
- name: J_R_HairTail_03
parentName: J_R_HairTail_02
position: {x: -0.000000038146972, y: -0.000000038146972, z: -0.17191932}
- rotation: {x: -1.6653337e-16, y: -0.000000014901158, z: -0.000000011175868, w: 1}
+ rotation: {x: -1.6653337e-16, y: -0.000000014901158, z: -0.000000011175868,
+ w: 1}
scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001}
- name: J_R_HeadRibbon_00
parentName: Character1_Head
@@ -714,7 +725,8 @@ ModelImporter:
- name: J_L_HairSide_02
parentName: J_L_HairSide_01
position: {x: -0.17118454, y: 0.000000009536743, z: 0.00000022888183}
- rotation: {x: 0.000000077299774, y: -0.00000008475035, z: -0.000000014901153, w: 1}
+ rotation: {x: 0.000000077299774, y: -0.00000008475035, z: -0.000000014901153,
+ w: 1}
scale: {x: 1.0000002, y: 1, z: 0.9999998}
- name: J_R_HairSide_00
parentName: Character1_Head
@@ -729,7 +741,8 @@ ModelImporter:
- name: J_R_HairSide_02
parentName: J_R_HairSide_01
position: {x: 0.17118447, y: 0.000000009536743, z: -0.00000016212464}
- rotation: {x: -0.00000069662923, y: 0.00000008195637, z: 0.000000029802383, w: 1}
+ rotation: {x: -0.00000069662923, y: 0.00000008195637, z: 0.000000029802383,
+ w: 1}
scale: {x: 0.9999999, y: 1.0000001, z: 0.9999996}
- name: bone_eye_L
parentName: Character1_Head
@@ -829,7 +842,8 @@ ModelImporter:
- name: Character1_RightHandPinky3
parentName: Character1_RightHandPinky2
position: {x: 0.0075922012, y: 0.00000013589859, z: -0.00000030517577}
- rotation: {x: -0.00000024121255, y: 0.00000025331983, z: -0.000000014901105, w: 1}
+ rotation: {x: -0.00000024121255, y: 0.00000025331983, z: -0.000000014901105,
+ w: 1}
scale: {x: 0.99999964, y: 1.0000001, z: 1}
- name: Character1_RightHandRing1
parentName: Character1_RightHand
@@ -844,7 +858,8 @@ ModelImporter:
- name: Character1_RightHandRing3
parentName: Character1_RightHandRing2
position: {x: 0.0100004, y: -0.000000009834766, z: -0.00000034332274}
- rotation: {x: 0.0000002421438, y: 0.000000029802315, z: -0.0000000022118978, w: 1}
+ rotation: {x: 0.0000002421438, y: 0.000000029802315, z: -0.0000000022118978,
+ w: 1}
scale: {x: 1.0000004, y: 1.0000001, z: 1.0000001}
- name: Character1_RightHandIndex1
parentName: Character1_RightHand
@@ -859,7 +874,8 @@ ModelImporter:
- name: Character1_RightHandIndex3
parentName: Character1_RightHandIndex2
position: {x: 0.010736103, y: -0.000000085830685, z: -0.00000015258789}
- rotation: {x: -0.000000007450581, y: 0.000000104308135, z: -0.000000016763806, w: 1}
+ rotation: {x: -0.000000007450581, y: 0.000000104308135, z: -0.000000016763806,
+ w: 1}
scale: {x: 0.9999998, y: 0.9999999, z: 1.0000004}
- name: Character1_RightHandMiddle1
parentName: Character1_RightHand
@@ -874,7 +890,8 @@ ModelImporter:
- name: Character1_RightHandMiddle3
parentName: Character1_RightHandMiddle2
position: {x: 0.012807674, y: 0.0000000667572, z: -0.00000087738033}
- rotation: {x: -0.0000000018626964, y: -0.00000092387177, z: -0.000000055879344, w: 1}
+ rotation: {x: -0.0000000018626964, y: -0.00000092387177, z: -0.000000055879344,
+ w: 1}
scale: {x: 1.0000001, y: 1, z: 0.9999999}
- name: J_R_ForeArm_00_tw
parentName: Character1_RightForeArm
@@ -1029,7 +1046,8 @@ ModelImporter:
- name: J_R_knee
parentName: Character1_RightUpLeg
position: {x: -0, y: 0.022121582, z: -0.15356168}
- rotation: {x: 0.0000000025893838, y: 0.000000009194991, z: 0.0000000023283064, w: 1}
+ rotation: {x: 0.0000000025893838, y: 0.000000009194991, z: 0.0000000023283064,
+ w: 1}
scale: {x: 1, y: 1, z: 1}
- name: utc_head
parentName: Utc_sum_humanoid(Clone)
@@ -1079,3 +1097,10 @@ ModelImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/SD_Kohaku_chanz/Utc_sum_humanoid.fbx
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan License Terms and Condition_EN_UCL2.0.pdf.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan License Terms and Condition_EN_UCL2.0.pdf.meta
index 7e370183..de7829ce 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan License Terms and Condition_EN_UCL2.0.pdf.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan License Terms and Condition_EN_UCL2.0.pdf.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/01Unity-Chan
+ License Terms and Condition_EN_UCL2.0.pdf
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan License Terms and Condition_Summary_EN_UCL2.0.pdf.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan License Terms and Condition_Summary_EN_UCL2.0.pdf.meta
index e99bae58..1e02e671 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan License Terms and Condition_Summary_EN_UCL2.0.pdf.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan License Terms and Condition_Summary_EN_UCL2.0.pdf.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/02Unity-Chan
+ License Terms and Condition_Summary_EN_UCL2.0.pdf
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication of License_EN_UCL2.0.pdf.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication of License_EN_UCL2.0.pdf.meta
index 6eaa3bd4..cc08eda0 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication of License_EN_UCL2.0.pdf.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication of License_EN_UCL2.0.pdf.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/English/03Indication
+ of License_EN_UCL2.0.pdf
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan License Terms and Condition_JP_UCL2.0.pdf.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan License Terms and Condition_JP_UCL2.0.pdf.meta
index e9d95989..cc01d966 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan License Terms and Condition_JP_UCL2.0.pdf.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan License Terms and Condition_JP_UCL2.0.pdf.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/01Unity-Chan
+ License Terms and Condition_JP_UCL2.0.pdf
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan License Terms and Condition_Summary_JP_UCL2.0.pdf.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan License Terms and Condition_Summary_JP_UCL2.0.pdf.meta
index 678f5b68..8969c88c 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan License Terms and Condition_Summary_JP_UCL2.0.pdf.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan License Terms and Condition_Summary_JP_UCL2.0.pdf.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/02Unity-Chan
+ License Terms and Condition_Summary_JP_UCL2.0.pdf
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication of License_JP_UCL2.0.pdf.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication of License_JP_UCL2.0.pdf.meta
index 69d2d752..71a62788 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication of License_JP_UCL2.0.pdf.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication of License_JP_UCL2.0.pdf.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/Japanese/03Indication
+ of License_JP_UCL2.0.pdf
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.ai.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.ai.meta
index 66e3eda7..9575c929 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.ai.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.ai.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/LUUL_LOGO_rules02.ai
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.psd.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.psd.meta
index cee4d9fa..f8fdc761 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.psd.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_LOGO_rules02.psd.meta
@@ -133,3 +133,11 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/LUUL_LOGO_rules02.psd
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline.pdf.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline.pdf.meta
index 6c4eca2f..b97ec614 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline.pdf.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline.pdf.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/LUUL_logo-guideline.pdf
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline_en.pdf.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline_en.pdf.meta
index 14cb0a16..ba773669 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline_en.pdf.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/LUUL_logo-guideline_en.pdf.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/LUUL_logo-guideline_en.pdf
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Dark_Silhouette.jpg.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Dark_Silhouette.jpg.meta
index f247ebd4..bfb6de0d 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Dark_Silhouette.jpg.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Dark_Silhouette.jpg.meta
@@ -133,3 +133,11 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/Others/jpg/Dark_Silhouette.jpg
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Light_Silhouette.jpg.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Light_Silhouette.jpg.meta
index 6497d7f9..84d85602 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Light_Silhouette.jpg.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/jpg/Light_Silhouette.jpg.meta
@@ -133,3 +133,11 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/Others/jpg/Light_Silhouette.jpg
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Dark_Silhouette.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Dark_Silhouette.png.meta
index ff1507d3..d7d7d0e5 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Dark_Silhouette.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Dark_Silhouette.png.meta
@@ -133,3 +133,11 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/Others/png/Dark_Silhouette.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Frame.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Frame.png.meta
index 3ea31d42..35d52fe9 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Frame.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Frame.png.meta
@@ -133,3 +133,11 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/Others/png/Light_Frame.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Silhouette.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Silhouette.png.meta
index 8c107994..0abf566c 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Silhouette.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/png/Light_Silhouette.png.meta
@@ -133,3 +133,11 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/Others/png/Light_Silhouette.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Dark_Silhouette.svg.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Dark_Silhouette.svg.meta
index f556b7d3..8295f26a 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Dark_Silhouette.svg.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Dark_Silhouette.svg.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/Others/svg/Dark_Silhouette.svg
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Frame.svg.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Frame.svg.meta
index 026f1e4c..1b0f8139 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Frame.svg.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Frame.svg.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/Others/svg/Light_Frame.svg
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Silhouette.svg.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Silhouette.svg.meta
index 2cbe484a..eca480f1 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Silhouette.svg.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License Logo/Others/svg/Light_Silhouette.svg.meta
@@ -5,3 +5,11 @@ DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UCL2.0/License
+ Logo/Others/svg/Light_Silhouette.svg
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt.meta
index 06b4096e..2adc6f26 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan License.txt.meta
@@ -5,3 +5,11 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/Unity-Chan
+ License.txt
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim.meta
index ac7246d3..0576d8ce 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/RUN00_F.anim
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky -WA-.fbx.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky -WA-.fbx.meta
index 58372d7f..bccaa898 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky -WA-.fbx.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky -WA-.fbx.meta
@@ -1139,3 +1139,11 @@ ModelImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/UC01_001_UniteInTheSky
+ -WA-.fbx
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim.meta
index 97a14dfe..3f27c2f5 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT02.anim
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim.meta
index 7998c131..4a9407dc 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WAIT04.anim
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim.meta
index 8ef36ead..c3100148 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WALK00_F.anim
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim.meta
index 6188edef..059cccb9 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Animation/WIN00.anim
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat.meta
index a574487f..efa01cdf 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Albedo.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body Back.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body Back.mat.meta
index 12cfeba1..70324ca1 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body Back.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body Back.mat.meta
@@ -6,3 +6,11 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body
+ Back.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat.meta
index 56774b83..4a580829 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat.meta
@@ -7,3 +7,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Body.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat.meta
index b901288f..6ffab132 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat.meta
@@ -7,3 +7,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat.meta
index 80ac406f..5895365a 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Eyes_HL.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat.meta
index a9db4277..011cc00b 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat.meta
@@ -7,3 +7,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Face.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat.meta
index fc702678..b1f3daa4 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat.meta
@@ -7,3 +7,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Hair.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat.meta
index 719a4638..90ecbfc2 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat.meta
@@ -7,3 +7,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/HairPony.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat.meta
index f858dbd1..61e89a10 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat.meta
@@ -7,3 +7,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Headgear.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve Back.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve Back.mat.meta
index 4d73bcf7..9f6702a5 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve Back.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve Back.mat.meta
@@ -6,3 +6,11 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve
+ Back.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat.meta
index 3dd40171..6012aeab 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat.meta
@@ -7,3 +7,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/LongSleeve.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat.meta
index ed5220cb..f262fdde 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat.meta
@@ -7,3 +7,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/Skin.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png.meta
index abe0c9ba..e55ecabb 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Base.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png.meta
index f44db686..9f183a74 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Emi.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png.meta
index 7e9d9cda..30a5d978 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_SGM.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png.meta
index 3654197e..c9ab2800 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd1.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png.meta
index 68eb45b2..9e8f71d6 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Shd2.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png.meta
index 4186c54a..3ec2a1c5 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Body_Spc.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png.meta
index fd685467..28721547 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Base.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png.meta
index 6b8446ba..4cfe5938 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Emi.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png.meta
index 54400b4e..2cbaaa97 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_LSM.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png.meta
index f40fe31e..cedb6221 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Rim.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png.meta
index 46e30702..c70d027e 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_SGM.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png.meta
index 0f7fa712..1820e574 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd1.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png.meta
index 65177a9b..934ff633 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Face_Shd2.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png.meta
index 063a0391..cbb1534a 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Hair_SGM.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png.meta
index f322c00b..fe494a9b 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Headfgear_Base.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png.meta
index 0b4455cf..85ff04d6 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Base.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png.meta
index 6217632c..4318be81 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Emi.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png.meta
index 9bd5b339..7e9e342d 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Nrm.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png.meta
index 0fa714a2..2960eee0 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Rim.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png.meta
index b25f5ab4..196427d1 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SGM.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png.meta
index fe3b4e05..d86396bd 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_Spc.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png.meta
index eecb6367..86198681 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png.meta
@@ -138,3 +138,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/TEX/PNG/Skin_SpcCol.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat.meta
index 3ef95aa0..48824728 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/face3_main.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat.meta
index f9977951..c94071f3 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/Materials/headExt.mat
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller.meta
index 60406f79..38be1232 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller.meta
@@ -6,3 +6,10 @@ NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UniteInTheSky.controller
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx.meta
index f7869cf0..175da030 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx.meta
@@ -1119,12 +1119,14 @@ ModelImporter:
- name: DB_HairPonny_E_06
parentName: DB_HairPonny_E_05
position: {x: -0.20536478, y: 0.0000000181024, z: -0.000000052352917}
- rotation: {x: 0.000000010306467, y: 0.00000037532288, z: -0.00000015743396, w: 1}
+ rotation: {x: 0.000000010306467, y: 0.00000037532288, z: -0.00000015743396,
+ w: 1}
scale: {x: 1, y: 1, z: 1}
- name: DB_HairPonny_E_07
parentName: DB_HairPonny_E_06
position: {x: -0.20241548, y: -0.000000007486665, z: -0.000000014204306}
- rotation: {x: -0.000000013092317, y: -0.0000013895333, z: 0.000000036315225, w: 1}
+ rotation: {x: -0.000000013092317, y: -0.0000013895333, z: 0.000000036315225,
+ w: 1}
scale: {x: 1, y: 1, z: 1}
- name: DB_HairPonny_E_08
parentName: DB_HairPonny_E_07
@@ -1379,7 +1381,8 @@ ModelImporter:
- name: DB_Sode_B_03_L
parentName: DB_Sode_B_02_L
position: {x: -0.00000003495618, y: 0.16377598, z: 0.00000008490355}
- rotation: {x: 0.00000043213367, y: -0.000000017451445, z: 0.000000006864544, w: 1}
+ rotation: {x: 0.00000043213367, y: -0.000000017451445, z: 0.000000006864544,
+ w: 1}
scale: {x: 1, y: 1, z: 1}
- name: DB_Sode_B_04_L
parentName: DB_Sode_B_03_L
@@ -1424,12 +1427,14 @@ ModelImporter:
- name: DB_Sode_A_05_L
parentName: DB_Sode_A_04_L
position: {x: 0.0000000058321894, y: 0.18826447, z: -0.000000033450405}
- rotation: {x: -0.0000031758095, y: -0.00000007047311, z: -0.000000009660246, w: 1}
+ rotation: {x: -0.0000031758095, y: -0.00000007047311, z: -0.000000009660246,
+ w: 1}
scale: {x: 1, y: 1, z: 1}
- name: DB_Sode_A_06_L
parentName: DB_Sode_A_05_L
position: {x: -0.00000004670306, y: 0.10419001, z: -0.00000009729876}
- rotation: {x: 0.0000025499612, y: -0.0000000085358245, z: 0.0000000013564954, w: 1}
+ rotation: {x: 0.0000025499612, y: -0.0000000085358245, z: 0.0000000013564954,
+ w: 1}
scale: {x: 1, y: 1, z: 1}
- name: DB_Sode_A_06_L_end
parentName: DB_Sode_A_06_L
@@ -1929,7 +1934,8 @@ ModelImporter:
- name: DB_Skirt_E_04_L
parentName: DB_Skirt_E_03_L
position: {x: -0.061201386, y: 0.0000000047683715, z: 0.00000004529953}
- rotation: {x: 0.00000017229465, y: 0.0000000018626438, z: -0.00000020489097, w: 1}
+ rotation: {x: 0.00000017229465, y: 0.0000000018626438, z: -0.00000020489097,
+ w: 1}
scale: {x: 0.99999994, y: 1.0000002, z: 1.0000001}
- name: DB_Skirt_E_04_L_end
parentName: DB_Skirt_E_04_L
@@ -1954,7 +1960,8 @@ ModelImporter:
- name: DB_Skirt_D_04_L
parentName: DB_Skirt_D_03_L
position: {x: -0.06120134, y: 0.000000028610229, z: 0.00000008167233}
- rotation: {x: -0.0000001379085, y: 0.000000059069862, z: -0.000000031664968, w: 1}
+ rotation: {x: -0.0000001379085, y: 0.000000059069862, z: -0.000000031664968,
+ w: 1}
scale: {x: 1, y: 1, z: 1}
- name: DB_Skirt_D_04_L_end
parentName: DB_Skirt_D_04_L
@@ -2004,7 +2011,8 @@ ModelImporter:
- name: DB_Skirt_D_04_R
parentName: DB_Skirt_D_03_R
position: {x: -0.061201222, y: 0.000000022649765, z: 0.0000000997819}
- rotation: {x: 0.00000008333883, y: -0.00000006679329, z: 0.0000000046566138, w: 1}
+ rotation: {x: 0.00000008333883, y: -0.00000006679329, z: 0.0000000046566138,
+ w: 1}
scale: {x: 1, y: 0.9999998, z: 0.9999999}
- name: DB_Skirt_D_04_R_end
parentName: DB_Skirt_D_04_R
@@ -2029,7 +2037,8 @@ ModelImporter:
- name: DB_Skirt_E_04_R
parentName: DB_Skirt_E_03_R
position: {x: -0.06120137, y: -0.000000052452087, z: 0.000000007152557}
- rotation: {x: -0.000000073574476, y: -0.00000002328306, z: 0.00000030547378, w: 1}
+ rotation: {x: -0.000000073574476, y: -0.00000002328306, z: 0.00000030547378,
+ w: 1}
scale: {x: 1.0000001, y: 1.0000001, z: 1.0000001}
- name: DB_Skirt_E_04_R_end
parentName: DB_Skirt_E_04_R
@@ -2054,7 +2063,8 @@ ModelImporter:
- name: DB_Skirt_C_04_R
parentName: DB_Skirt_C_03_R
position: {x: -0.061201274, y: 0.000000007897615, z: 0.000000007152557}
- rotation: {x: 0.000000013969838, y: 0.0000000015133992, z: 0.0000000942091, w: 1}
+ rotation: {x: 0.000000013969838, y: 0.0000000015133992, z: 0.0000000942091,
+ w: 1}
scale: {x: 1, y: 1, z: 1.0000001}
- name: DB_Skirt_C_04_R_end
parentName: DB_Skirt_C_04_R
@@ -2079,7 +2089,8 @@ ModelImporter:
- name: DB_Skirt_B_04_R
parentName: DB_Skirt_B_03_R
position: {x: -0.061201327, y: 0.000000023841856, z: -0.000000014305114}
- rotation: {x: -0.000000018626448, y: -0.00000012479722, z: -0.00000025518239, w: 1}
+ rotation: {x: -0.000000018626448, y: -0.00000012479722, z: -0.00000025518239,
+ w: 1}
scale: {x: 1, y: 1.0000001, z: 1.0000001}
- name: DB_Skirt_B_04_R_end
parentName: DB_Skirt_B_04_R
@@ -2114,7 +2125,8 @@ ModelImporter:
- name: DB_Skirt_A_05_R
parentName: DB_Skirt_A_04_R
position: {x: -0.068666466, y: -0.0000000011920929, z: 0.000000023841856}
- rotation: {x: -0.000000070780516, y: -0.000000027008351, z: 0.000000088475645, w: 1}
+ rotation: {x: -0.000000070780516, y: -0.000000027008351, z: 0.000000088475645,
+ w: 1}
scale: {x: 1.0000001, y: 1, z: 1.0000001}
- name: DB_Skirt_A_05_R_end
parentName: DB_Skirt_A_05_R
@@ -2245,3 +2257,10 @@ ModelImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA.fbx
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab
index 95d1c929..59845608 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:30248c993012647c1ae3c5d3dc4682a436cbee16ddf1d480e4cbd79d71fa046d
-size 840671
+oid sha256:14cdc785604144bb02b06bc56d2439eafe6035c3aa279ca90edc94824ab1c3c1
+size 1050073
diff --git a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab.meta b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab.meta
index 1f4b6144..0eb1ab18 100644
--- a/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab.meta
+++ b/Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab.meta
@@ -5,3 +5,10 @@ PrefabImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Example (Can be deleted)/UnityChan/UnityChanKAGURA/UnityCHanKAGURA_MC2.prefab
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/MagicaCloth2.asmdef.meta b/Assets/External/MagicaCloth2/MagicaCloth2.asmdef.meta
index 8be1cce3..27377342 100644
--- a/Assets/External/MagicaCloth2/MagicaCloth2.asmdef.meta
+++ b/Assets/External/MagicaCloth2/MagicaCloth2.asmdef.meta
@@ -5,3 +5,10 @@ AssemblyDefinitionImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/MagicaCloth2.asmdef
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Readme.txt.meta b/Assets/External/MagicaCloth2/Readme.txt.meta
index 34934921..cbdd5391 100644
--- a/Assets/External/MagicaCloth2/Readme.txt.meta
+++ b/Assets/External/MagicaCloth2/Readme.txt.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Readme.txt
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Readme_jpn.txt.meta b/Assets/External/MagicaCloth2/Readme_jpn.txt.meta
index c0c1039a..735fb715 100644
--- a/Assets/External/MagicaCloth2/Readme_jpn.txt.meta
+++ b/Assets/External/MagicaCloth2/Readme_jpn.txt.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Readme_jpn.txt
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Icon/icon-cloth.png.meta b/Assets/External/MagicaCloth2/Res/Icon/icon-cloth.png.meta
index 87a8e234..93c678e0 100644
--- a/Assets/External/MagicaCloth2/Res/Icon/icon-cloth.png.meta
+++ b/Assets/External/MagicaCloth2/Res/Icon/icon-cloth.png.meta
@@ -122,3 +122,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Icon/icon-cloth.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Icon/icon-collider.png.meta b/Assets/External/MagicaCloth2/Res/Icon/icon-collider.png.meta
index f418d040..6532b4a7 100644
--- a/Assets/External/MagicaCloth2/Res/Icon/icon-collider.png.meta
+++ b/Assets/External/MagicaCloth2/Res/Icon/icon-collider.png.meta
@@ -134,3 +134,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Icon/icon-collider.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Icon/icon-settings.png.meta b/Assets/External/MagicaCloth2/Res/Icon/icon-settings.png.meta
index dcb317a8..60d893a2 100644
--- a/Assets/External/MagicaCloth2/Res/Icon/icon-settings.png.meta
+++ b/Assets/External/MagicaCloth2/Res/Icon/icon-settings.png.meta
@@ -133,3 +133,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Icon/icon-settings.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Icon/icon-wind.png.meta b/Assets/External/MagicaCloth2/Res/Icon/icon-wind.png.meta
index e23a34f8..7a8bb290 100644
--- a/Assets/External/MagicaCloth2/Res/Icon/icon-wind.png.meta
+++ b/Assets/External/MagicaCloth2/Res/Icon/icon-wind.png.meta
@@ -133,3 +133,10 @@ TextureImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Icon/icon-wind.png
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json
index c5081e22..13048cca 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c1e2f79971878ba5c297838ad35991c32cf4a3a024b2b3f41a6bb84ce37d40dd
-size 4902
+oid sha256:9230b1b99e7f2a1a4792abd4aa390a94944a620e166e3b5268f64106f17f07d6
+size 6293
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json.meta
index 3723e494..55a7a181 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json.meta
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Accessory.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json
index f58e28f7..b09d1003 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:a231cd5bb894f1c2295a5f594c1a8e48e6888bb4dd59a12041ad8ead1b8c0f38
-size 4898
+oid sha256:e9d58113a22f6e8405a83f620ffc94255740d6d2f47515f921f30dbf2a6d21a9
+size 6288
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json.meta
index 27684048..d0f11c03 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json.meta
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Cape.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json
index 419d135a..6702b2ed 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:bc579add2e2753d68f81019fdc09f68b596242641c0ea1cfa4a2a0a915f67420
-size 4914
+oid sha256:c4525fcb0d6edbdf1cb9be2320e0183d2b16c0431174a7bfbf77d7b1045477ff
+size 6304
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json.meta
index 39cbb35c..ff6d5424 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json.meta
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_FrontHair.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json
index daf19306..ccc8f82c 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:6d12e5a64e15cd95ea369aa7699fbbc9ae4611cdf2beb13586b4efb2d0336cf6
-size 6101
+oid sha256:547af0e1cd8f916d6157753c9558eabd5c1b1a605aac76e82014afb828ab9a45
+size 6151
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json.meta
index e584ffdf..852a34f3 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json.meta
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_HardSpring.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json
index ce8555d7..5a056159 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d5fba83920709e7503a59ed4947fb7004747ffde7af0205a56222ac6dee414ca
-size 5080
+oid sha256:bca2069de6a5b90981188c4f1292c6ad78b2cd3e090f35373c4d14dc36418703
+size 6485
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json.meta
index 55826ab6..1ec8ac23 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json.meta
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_LongHair.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json
index ed94b553..76634848 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:2ada23826e292294dfba2aa624b859fcbd04e8cb9a7bc6da6f11e727ca1b5173
-size 6102
+oid sha256:88480173e4c0cf1c93b6ac45231c3469d338b381ff862666572b69075a49f2cd
+size 6152
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json.meta
index 1e6dff93..432d56c5 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json.meta
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_MiddleSpring.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json
index 3ee1664a..ca590f71 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:31fc5c1073d88e4f75f78e2509d4e1299c70d0fd21bd6f492fa2a444ca76a8e9
-size 5008
+oid sha256:f1a20e0284bd5a7aa34d85d7dbc87b3117037d415d24b931066cec8b15143010
+size 6414
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json.meta
index 7e5065aa..e3dd10d3 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json.meta
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_ShortHair.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json
index 2c9415cc..0362d9ca 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9082a88f302870cd33e34319af2daad3d0f78ff77a30f007e6cc475dba89ed33
-size 5101
+oid sha256:ce17b1e7c8ec0e0a7e64828384d05c13da8efc0e7abdbb9f0bcb08c8eea2eb87
+size 6508
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json.meta
index 67d7483f..e2095825 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json.meta
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Skirt.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json
new file mode 100644
index 00000000..4a608d31
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:08cc9455ecf800a606e73203f9c84603701e66a20348127da80a97a40420c9c7
+size 6575
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json.meta
new file mode 100644
index 00000000..87c02083
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json.meta
@@ -0,0 +1,14 @@
+fileFormatVersion: 2
+guid: 95115815f2f656045acda9f116a05915
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSkirt.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json
index b01a96e8..a6ca0c60 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:5e476689a1a4857eb5466e7c82f9e502601aab545ecd3b646caf49dc68f21c50
-size 6102
+oid sha256:6ac65e79b165e423c680750ec4a5b3cd30b77b4755dc4b9e378823e17ee6149a
+size 6152
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json.meta
index 68b796c5..8a13529c 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json.meta
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_SoftSpring.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json
index c472494e..dd624ba2 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e8ed1e9b4d1f4d482521d762c3dd12673caeaa3751ca310205b8f0ce4cbb93d5
-size 4974
+oid sha256:84399b8b65a155eadda37d373a27d89e268dfd987dbdb8f4cef21a194cf39dcf
+size 6343
diff --git a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json.meta b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json.meta
index 157dcd0a..f043e278 100644
--- a/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json.meta
+++ b/Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json.meta
@@ -5,3 +5,10 @@ TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Res/Preset/MC2_Preset_Tail.json
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs.meta
index 5409c2cc..b34b1598 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/CheckSliderSerializeData.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs
index 4982c975..13c645cc 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs
@@ -19,5 +19,11 @@ namespace MagicaCloth2
{
return 0;
}
+
+ ///
+ /// Gizmo display state.
+ ///
+ public bool IsGizmoVisible { get; set; }
+ protected virtual void OnDrawGizmos() => IsGizmoVisible = true;
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs.meta
index 2e8a2772..ce3d5044 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothBehaviour.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs.meta
index 3f6669b0..73f902d6 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothForceMode.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs
new file mode 100644
index 00000000..7e3e4ab4
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs
@@ -0,0 +1,211 @@
+// Magica Cloth 2.
+// Copyright (c) 2025 MagicaSoft.
+// https://magicasoft.jp
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace MagicaCloth2
+{
+ ///
+ /// 初期化データ
+ ///
+ [System.Serializable]
+ public class ClothInitSerializeData : ITransform
+ {
+ public const int InitDataVersion = 2;
+
+ public int initVersion;
+ public int localHash;
+ public int globalHash;
+ public ClothProcess.ClothType clothType;
+ public TransformRecordSerializeData clothTransformRecord;
+ public TransformRecordSerializeData normalAdjustmentTransformRecord;
+ public List customSkinningBoneRecords;
+ public List clothSetupDataList;
+
+ public bool HasData()
+ {
+ if (initVersion == 0)
+ return false;
+ if (localHash == 0 || globalHash == 0)
+ return false;
+
+ return true;
+ }
+
+ public void Clear()
+ {
+ initVersion = 0;
+ localHash = 0;
+ globalHash = 0;
+ clothType = ClothProcess.ClothType.MeshCloth;
+ clothTransformRecord = new TransformRecordSerializeData();
+ normalAdjustmentTransformRecord = new TransformRecordSerializeData();
+ customSkinningBoneRecords = new List();
+ clothSetupDataList = new List();
+ }
+
+ public ResultCode DataValidate(ClothProcess cprocess)
+ {
+ if (localHash == 0 || globalHash == 0)
+ return new ResultCode(Define.Result.InitSerializeData_InvalidHash);
+ if (initVersion == 0)
+ return new ResultCode(Define.Result.InitSerializeData_InvalidVersion);
+
+ if (clothSetupDataList == null || clothSetupDataList.Count == 0)
+ return new ResultCode(Define.Result.InitSerializeData_InvalidSetupData);
+
+ var cloth = cprocess.cloth;
+ var sdata = cloth.SerializeData;
+
+ if (clothType != sdata.clothType)
+ return new ResultCode(Define.Result.InitSerializeData_ClothTypeMismatch);
+
+ if (clothType == ClothProcess.ClothType.MeshCloth)
+ {
+ int rendererCount = sdata.sourceRenderers.Count;
+ if (clothSetupDataList.Count != rendererCount)
+ return new ResultCode(Define.Result.InitSerializeData_SetupCountMismatch);
+
+ // 各レンダラー情報の検証
+ for (int i = 0; i < rendererCount; i++)
+ {
+ if (clothSetupDataList[i].DataValidateMeshCloth(sdata.sourceRenderers[i]) == false)
+ return new ResultCode(Define.Result.InitSerializeData_MeshClothSetupValidationError);
+ }
+ }
+ else if (clothType == ClothProcess.ClothType.BoneCloth)
+ {
+ if (clothSetupDataList.Count != 1)
+ return new ResultCode(Define.Result.InitSerializeData_SetupCountMismatch);
+
+ if (clothSetupDataList[0].DataValidateBoneCloth(sdata, RenderSetupData.SetupType.BoneCloth) == false)
+ return new ResultCode(Define.Result.InitSerializeData_BoneClothSetupValidationError);
+ }
+ else if (clothType == ClothProcess.ClothType.BoneSpring)
+ {
+ if (clothSetupDataList.Count != 1)
+ return new ResultCode(Define.Result.InitSerializeData_SetupCountMismatch);
+
+ if (clothSetupDataList[0].DataValidateBoneCloth(sdata, RenderSetupData.SetupType.BoneSpring) == false)
+ return new ResultCode(Define.Result.InitSerializeData_BoneSpringSetupValidationError);
+ }
+
+ // カスタムスキニングボーン
+ if (sdata.customSkinningSetting.skinningBones.Count != customSkinningBoneRecords.Count)
+ return new ResultCode(Define.Result.InitSerializeData_CustomSkinningBoneCountMismatch);
+
+ // V1かつMeshClothかつSkinnedMeshRendererの場合のみ、(Clone)メッシュ利用時は無効とする
+ // これは(Clone)メッシュを再度加工することによりボーンウエイトなどのデータがおかしくなりエラーが発生するため
+ if (initVersion <= 1 && clothType == ClothProcess.ClothType.MeshCloth)
+ {
+ for (int i = 0; i < sdata.sourceRenderers.Count; i++)
+ {
+ SkinnedMeshRenderer sren = sdata.sourceRenderers[i] as SkinnedMeshRenderer;
+ if (sren && sren.sharedMesh && sren.sharedMesh.name.Contains("(Clone)"))
+ {
+ return new ResultCode(Define.Result.InitSerializeData_InvalidCloneMesh);
+ }
+ }
+ }
+
+ return ResultCode.Success;
+ }
+
+ public bool Serialize(
+ ClothSerializeData sdata,
+ TransformRecord clothTransformRecord,
+ TransformRecord normalAdjustmentTransformRecord,
+ List setupList
+ )
+ {
+ initVersion = InitDataVersion; // version
+
+ clothType = sdata.clothType;
+
+ this.clothTransformRecord = new TransformRecordSerializeData();
+ this.clothTransformRecord.Serialize(clothTransformRecord);
+
+ this.normalAdjustmentTransformRecord = new TransformRecordSerializeData();
+ this.normalAdjustmentTransformRecord.Serialize(normalAdjustmentTransformRecord);
+
+ // カスタムスキニングボーン
+ customSkinningBoneRecords = new List();
+ int bcnt = sdata.customSkinningSetting.skinningBones.Count;
+ for (int i = 0; i < bcnt; i++)
+ {
+ var tr = new TransformRecord(sdata.customSkinningSetting.skinningBones[i], read: true);
+ var trs = new TransformRecordSerializeData();
+ trs.Serialize(tr);
+ customSkinningBoneRecords.Add(trs);
+ }
+
+ // setup data
+ clothSetupDataList = new List();
+ if (setupList != null && setupList.Count > 0)
+ {
+ foreach (var setup in setupList)
+ {
+ var meshSetupData = new RenderSetupSerializeData();
+ meshSetupData.Serialize(setup);
+ clothSetupDataList.Add(meshSetupData);
+ }
+ }
+
+ localHash = GetLocalHash();
+ globalHash = GetGlobalHash();
+
+ return true;
+ }
+
+
+ public void GetUsedTransform(HashSet transformSet)
+ {
+ clothTransformRecord?.GetUsedTransform(transformSet);
+ normalAdjustmentTransformRecord?.GetUsedTransform(transformSet);
+ customSkinningBoneRecords?.ForEach(x => x.GetUsedTransform(transformSet));
+ clothSetupDataList?.ForEach(x => x.GetUsedTransform(transformSet));
+ }
+
+ public void ReplaceTransform(Dictionary replaceDict)
+ {
+ clothTransformRecord?.ReplaceTransform(replaceDict);
+ normalAdjustmentTransformRecord?.ReplaceTransform(replaceDict);
+ customSkinningBoneRecords?.ForEach(x => x.ReplaceTransform(replaceDict));
+ clothSetupDataList?.ForEach(x => x.ReplaceTransform(replaceDict));
+ }
+
+ int GetLocalHash()
+ {
+ // ローカルハッシュ
+ // ・編集用メッシュが再構築されるたびにこのハッシュで保存チェックされる
+ // ・各種カウント+配列数
+ // ・Transformの姿勢は無視する。ただし階層構造の変更は見る
+ int hash = 0;
+ hash += initVersion * 9876;
+ hash += (int)clothType * 5656;
+ hash += clothTransformRecord?.GetLocalHash() ?? 0;
+ hash += normalAdjustmentTransformRecord?.GetLocalHash() ?? 0;
+ customSkinningBoneRecords?.ForEach(x => hash += x?.GetLocalHash() ?? 0);
+ clothSetupDataList?.ForEach(x => hash += x?.GetLocalHash() ?? 0);
+
+ return hash;
+ }
+
+ int GetGlobalHash()
+ {
+ // グローバルハッシュ
+ // ・頂点ペイント終了時にこのハッシュで保存チェックされる
+ // ・保存チェックにはローカルハッシュも含まれる
+ // ・Transformのローカル姿勢を見る(localPosition/localRotation/localScale)
+ // ・ただしSetupDataのinitRenderScaleのみワールドスケールをチェックする
+ int hash = 0;
+ hash += clothTransformRecord?.GetGlobalHash() ?? 0;
+ hash += normalAdjustmentTransformRecord?.GetGlobalHash() ?? 0;
+ customSkinningBoneRecords?.ForEach(x => hash += x?.GetGlobalHash() ?? 0);
+ clothSetupDataList?.ForEach(x => hash += x?.GetGlobalHash() ?? 0);
+
+ return hash;
+ }
+ }
+}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs.meta
new file mode 100644
index 00000000..218507a6
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs.meta
@@ -0,0 +1,18 @@
+fileFormatVersion: 2
+guid: 87cb8cdfb6686334d904a1e0c0536944
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothInitSerializeData.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs
new file mode 100644
index 00000000..f32a33a7
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs
@@ -0,0 +1,25 @@
+// Magica Cloth 2.
+// Copyright (c) 2024 MagicaSoft.
+// https://magicasoft.jp
+
+namespace MagicaCloth2
+{
+ ///
+ /// メッシュへの書き込み対象
+ /// Write target to mesh.
+ ///
+ public enum ClothMeshWriteMode
+ {
+ ///
+ /// 位置と法線
+ /// Position, Normal
+ ///
+ PositionAndNormal = 0,
+
+ ///
+ /// 位置と法線と接線
+ /// Position, Normal, Tangent
+ ///
+ PositionAndNormalTangent = 1,
+ }
+}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs.meta
new file mode 100644
index 00000000..bcdb8c16
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs.meta
@@ -0,0 +1,18 @@
+fileFormatVersion: 2
+guid: c89429b06b0fde045af1104d0fe4d6b9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothMeshWriteMode.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs.meta
index 0774aafe..a83f4acd 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothNormalAxis.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs
index 680f8b72..90ac7c2f 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs
@@ -24,7 +24,7 @@ namespace MagicaCloth2
///
/// 重力方向(ワールド空間)
///
- public float3 gravityDirection;
+ public float3 worldGravityDirection;
///
/// 初期姿勢での重力の減衰率(0.0 ~ 1.0)
@@ -63,6 +63,9 @@ namespace MagicaCloth2
public float rotationalInterpolation;
public float rootRotation;
+ // カリング(Culling)
+ public CullingSettings.CullingParams culling;
+
// 慣性制約(Inertia)
public InertiaConstraint.InertiaConstraintParams inertiaConstraint;
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs.meta
index e69e8ba0..c42e7743 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothParameters.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs
index aee4aa12..df7e205f 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs
@@ -9,6 +9,7 @@ using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
+using Unity.Profiling;
using UnityEngine;
namespace MagicaCloth2
@@ -19,107 +20,253 @@ namespace MagicaCloth2
public partial class ClothProcess
{
//=========================================================================================
+ static readonly ProfilerMarker initClothProfiler = new ProfilerMarker("InitCloth");
+
///
- /// 初期化(★必ずアニメーションの実行前に行う)
+ /// 初期化(必ずアニメーションの実行前に行う)
///
internal void Init()
{
Debug.Assert(cloth);
- Develop.DebugLog($"Init start :{cloth.name}");
+ Develop.DebugLog($"Init start [{cloth.name}]");
+ initClothProfiler.Begin();
+ result.SetSuccess();
+ InitDataResult.Clear();
- // すでに初期化済みならスキップ
- if (IsState(State_InitComplete))
+ try
{
- return;
- }
-
- // すでに破棄されている場合はエラーとする。再初期化はできない
- if (isDestory)
- {
- Develop.LogError($"Already destroyed components cannot be reinitialized.");
- return;
- }
-
- SetState(State_Valid, false);
- result.SetProcess();
- var sdata = cloth.SerializeData;
-
- // クロスを生成するための最低限の情報が揃っているかチェックする
- if (sdata.IsValid() == false)
- {
- //result.SetResult(Define.Result.Empty);
- result.SetResult(sdata.VerificationResult);
- return;
- }
-
- // 基本情報
- clothType = sdata.clothType;
- reductionSettings = sdata.reductionSetting;
- parameters = sdata.GetClothParameters();
-
- // 初期トランスフォーム状態
- clothTransformRecord = new TransformRecord(cloth.ClothTransform);
-
- // 法線調整用トランスフォーム
- normalAdjustmentTransformRecord = new TransformRecord(
- sdata.normalAlignmentSetting.adjustmentTransform ?
- sdata.normalAlignmentSetting.adjustmentTransform :
- cloth.ClothTransform);
-
- // レンダラーとセットアップ情報の初期化
- if (clothType == ClothType.MeshCloth)
- {
- // MeshCloth
- // 必要なレンダラーを登録する
- foreach (var ren in sdata.sourceRenderers)
+ // すでに破棄されている場合はエラーとする。再初期化はできない
+ if (isDestory)
{
- if (ren)
+ Develop.LogError($"Already destroyed components cannot be reinitialized.");
+ throw new OperationCanceledException();
+ }
+
+ // すでに初期化済みならスキップ
+ if (IsState(State_InitComplete))
+ {
+ throw new OperationCanceledException();
+ }
+
+ var sdata = cloth.SerializeData;
+ var sdata2 = cloth.GetSerializeData2();
+
+ SetState(State_Valid, false);
+
+ // アニメーション用プロパティ初期化
+ cloth.InitAnimationProperty();
+
+ // クロスを生成するための最低限の情報が揃っているかチェックする
+ if (sdata.IsValid() == false)
+ {
+ result.SetResult(sdata.VerificationResult);
+ throw new OperationCanceledException();
+ }
+
+ // クロスの状態検証
+ var statusResult = GenerateStatusCheck();
+ result.Merge(statusResult);
+ if (statusResult.IsError())
+ {
+ throw new MagicaClothProcessingException();
+ }
+
+ SetState(State_InitComplete, true);
+
+ // PreBuildデータの利用と検証
+ bool usePreBuildData = sdata2.preBuildData.UsePreBuild();
+ SharePreBuildData sharePreBuildData = null;
+ if (usePreBuildData)
+ {
+ SetState(State_UsePreBuild, true);
+ var r = sdata2.preBuildData.DataValidate();
+ if (r.IsFaild())
{
- int handle = AddRenderer(ren);
- if (handle == 0)
+ result.Merge(r);
+ throw new OperationCanceledException();
+ }
+
+ sharePreBuildData = sdata2.preBuildData.GetSharePreBuildData();
+ }
+
+ // 初期化データの利用と検証
+ bool useInitData = false;
+#if !MC2_DISABLE_INITDATA
+ if (usePreBuildData == false && sdata2.initData != null && sdata2.initData.HasData())
+ {
+ // 初期化データ検証
+ InitDataResult = sdata2.initData.DataValidate(this);
+ useInitData = InitDataResult.IsSuccess();
+ if (InitDataResult.IsSuccess())
+ Develop.DebugLog($"InitData validation [{cloth.name}] : {InitDataResult.GetResultString()}");
+ else
+ {
+ Develop.DebugLogWarning($"InitData validation [{cloth.name}] : {InitDataResult.GetResultString()}");
+ Develop.DebugLogWarning("Do not use InitData.");
+ }
+ }
+#endif
+
+ // 基本情報
+ clothType = sdata.clothType;
+ reductionSettings = sdata.reductionSetting;
+ parameters = sdata.GetClothParameters();
+
+ // 初期トランスフォーム状態
+ clothTransformRecord = new TransformRecord(cloth.ClothTransform, read: useInitData == false);
+ if (usePreBuildData)
+ {
+ // Pre-Buildでは編集時スケールを復元する
+ clothTransformRecord.scale = sharePreBuildData.buildScale;
+ }
+ if (useInitData)
+ {
+ // initDataから復元
+ sdata2.initData.clothTransformRecord.Deserialize(clothTransformRecord);
+ }
+
+ // 法線調整用トランスフォーム
+ normalAdjustmentTransformRecord = new TransformRecord(
+ sdata.normalAlignmentSetting.adjustmentTransform ?
+ sdata.normalAlignmentSetting.adjustmentTransform :
+ cloth.ClothTransform, read: useInitData == false);
+ if (useInitData)
+ {
+ // initDataから復元
+ sdata2.initData.normalAdjustmentTransformRecord.Deserialize(normalAdjustmentTransformRecord);
+ }
+
+ // PreBuildデータの登録
+ PreBuildManager.ShareDeserializationData sharePreBuildDeserializeData = usePreBuildData ? MagicaManager.PreBuild.RegisterPreBuildData(sharePreBuildData, true) : null;
+ UniquePreBuildData uniquePreBuildData = usePreBuildData ? sdata2.preBuildData.uniquePreBuildData : null;
+
+ // レンダラーとセットアップ情報の初期化
+ // なおセットアップ情報はVirtualMeshを生成するためのものなのでベイク構築時は不要
+ if (clothType == ClothType.MeshCloth)
+ {
+ // MeshCloth
+ // 必要なレンダラーを登録する
+ for (int i = 0; i < sdata.sourceRenderers.Count; i++)
+ {
+ var ren = sdata.sourceRenderers[i];
+ if (ren)
{
- result.SetError(Define.Result.ClothInit_FailedAddRenderer);
- return;
- }
- var rdata = MagicaManager.Render.GetRendererData(handle);
- result.Merge(rdata.Result);
- if (rdata.Result.IsFaild())
- {
- return;
+ // PreBuildではセットアップ情報を復元する
+ RenderSetupData setup = null;
+ RenderSetupData.UniqueSerializationData uniquePreBuildSetupData = null;
+ if (usePreBuildData)
+ {
+ setup = sharePreBuildDeserializeData.renderSetupDataList[i];
+ uniquePreBuildSetupData = uniquePreBuildData.renderSetupDataList[i];
+
+ if (setup.result.IsFaild())
+ {
+ setup.Dispose();
+ result.SetError(Define.Result.PreBuild_SetupDeserializationError);
+ throw new OperationCanceledException();
+ }
+ }
+
+ // 初期化データの参照
+ RenderSetupSerializeData initSetupData = useInitData ? sdata2.initData.clothSetupDataList[i] : null;
+
+ int handle = AddRenderer(ren, setup, uniquePreBuildSetupData, initSetupData);
+ if (handle == 0)
+ {
+ result.SetError(Define.Result.ClothInit_FailedAddRenderer);
+ throw new OperationCanceledException();
+ }
+ var rdata = MagicaManager.Render.GetRendererData(handle);
+ result.Merge(rdata.Result);
+ if (rdata.Result.IsFaild())
+ {
+ throw new OperationCanceledException();
+ }
}
}
}
+ else if (clothType == ClothType.BoneCloth && usePreBuildData == false)
+ {
+ // BoneCloth
+ CreateBoneRenderSetupData(
+ useInitData ? sdata2.initData : null,
+ clothType, sdata.rootBones, null, sdata.connectionMode
+ );
+ }
+ else if (clothType == ClothType.BoneSpring && usePreBuildData == false)
+ {
+ // BoneSpring
+ // BoneSpringではLine接続のみ
+ CreateBoneRenderSetupData(
+ useInitData ? sdata2.initData : null,
+ clothType, sdata.rootBones, sdata.colliderCollisionConstraint.collisionBones, RenderSetupData.BoneConnectionMode.Line
+ );
+ }
+
+ // カスタムスキニングのボーン情報
+ int bcnt = sdata.customSkinningSetting.skinningBones.Count;
+ for (int i = 0; i < bcnt; i++)
+ {
+ var tr = new TransformRecord(sdata.customSkinningSetting.skinningBones[i], read: useInitData == false);
+ if (useInitData)
+ {
+ // initDataから復元
+ sdata2.initData.customSkinningBoneRecords[i].Deserialize(tr);
+ }
+ customSkinningBoneRecords.Add(tr);
+ }
+
+ // 同期コンポーネントの解決と作業バッファへの登録
+ var syncPartnerCloth = cloth.SyncPartnerCloth;
+ if (syncPartnerCloth)
+ {
+ // partner
+ MagicaManager.Team.comp2SyncPartnerCompMap.Add(cloth.GetInstanceID(), syncPartnerCloth.GetInstanceID());
+
+ // top
+ // デッドロック対策
+ var c = syncPartnerCloth;
+ while (c)
+ {
+ if (c == cloth)
+ c = null;
+ else if (c.SyncPartnerCloth)
+ c = c.SyncPartnerCloth;
+ else
+ break;
+ }
+ Debug.Assert(c);
+ SyncTopCloth = c;
+ MagicaManager.Team.comp2SyncTopCompMap.Add(cloth.GetInstanceID(), SyncTopCloth.GetInstanceID());
+ }
+
+ result.SetSuccess();
+ SetState(State_Valid, true);
+ SetState(State_InitSuccess, true);
+ SetState(State_Verification, true);
+
+ // この時点でクロスコンポーネントが非アクティブの場合は破棄監視リストに登録する
+ if (cloth.isActiveAndEnabled == false)
+ MagicaManager.Team.AddMonitoringProcess(this);
}
- else if (clothType == ClothType.BoneCloth)
+ catch (OperationCanceledException)
{
- // BoneCloth
- // 必要なボーンを登録する
- AddBoneCloth(clothType, sdata.rootBones, null, sdata.connectionMode);
}
- else if (clothType == ClothType.BoneSpring)
+ catch (MagicaClothProcessingException)
{
- // BoneSpring
- // 必要なボーンを登録する
- // BoneSpringではLine接続のみ
- AddBoneCloth(clothType, sdata.rootBones, sdata.colliderCollisionConstraint.collisionBones, RenderSetupData.BoneConnectionMode.Line);
}
-
- // カスタムスキニングのボーン情報
- int bcnt = sdata.customSkinningSetting.skinningBones.Count;
- for (int i = 0; i < bcnt; i++)
+ catch (Exception exception)
{
- customSkinningBoneRecords.Add(new TransformRecord(sdata.customSkinningSetting.skinningBones[i]));
+ Debug.LogException(exception);
+ result.SetError(Define.Result.ClothProcess_Exception);
}
- result.SetSuccess();
- SetState(State_Valid, true);
- SetState(State_InitComplete, true);
+ initClothProfiler.End();
- // この時点でクロスコンポーネントが非アクティブの場合は破棄監視リストに登録する
- if (cloth.isActiveAndEnabled == false)
- MagicaManager.Team.AddMonitoringProcess(this);
-
- Develop.DebugLog($"Init finish :{cloth.name}");
+ if (result.IsSuccess())
+ Develop.DebugLog($"Cloth Initialize Success! [{cloth.name}]");
+ else
+ Develop.DebugLogError($"Cloth Initialize failure! [{cloth.name}] : {result.GetResultString()}");
}
///
@@ -128,7 +275,12 @@ namespace MagicaCloth2
///
///
/// レンダー情報ハンドル
- int AddRenderer(Renderer ren)
+ int AddRenderer(
+ Renderer ren,
+ RenderSetupData referenceSetupData,
+ RenderSetupData.UniqueSerializationData referenceUniqueSetupData,
+ RenderSetupSerializeData referenceInitSetupData
+ )
{
if (ren == null)
return 0;
@@ -139,7 +291,7 @@ namespace MagicaCloth2
if (renderHandleList.Contains(handle) == false)
{
// レンダラーの利用開始
- handle = MagicaManager.Render.AddRenderer(ren);
+ handle = MagicaManager.Render.AddRenderer(ren, referenceSetupData, referenceUniqueSetupData, referenceInitSetupData);
if (handle != 0)
{
lock (lockObject)
@@ -159,10 +311,17 @@ namespace MagicaCloth2
///
///
///
- void AddBoneCloth(ClothType ctype, List rootTransforms, List collisionBones, RenderSetupData.BoneConnectionMode connectionMode)
+ void CreateBoneRenderSetupData(
+ ClothInitSerializeData initData,
+ ClothType ctype,
+ List rootTransforms,
+ List collisionBones,
+ RenderSetupData.BoneConnectionMode connectionMode
+ )
{
// BoneCloth用のセットアップデータ作成
boneClothSetupData = new RenderSetupData(
+ initData != null ? initData.clothSetupDataList[0] : null,
ctype == ClothType.BoneSpring ? RenderSetupData.SetupType.BoneSpring : RenderSetupData.SetupType.BoneCloth,
clothTransformRecord.transform,
rootTransforms,
@@ -172,19 +331,6 @@ namespace MagicaCloth2
);
}
-#if false
- ///
- /// セレクションデータハッシュとレンダラーハッシュを1つに結合したものを返す
- ///
- ///
- ///
- ///
- int GetSelectionAndRenderMixHash(int selectionHash, int renderHash)
- {
- return selectionHash + renderHash;
- }
-#endif
-
///
/// 有効化
///
@@ -193,20 +339,8 @@ namespace MagicaCloth2
if (MagicaManager.IsPlaying() == false)
return;
- // 有効化
- SetState(State_Enable, true);
-
- // チーム有効化
- MagicaManager.Team.SetEnable(TeamId, true);
-
- // レンダラー有効化
- if (renderHandleList != null)
- {
- foreach (int renderHandle in renderHandleList)
- {
- MagicaManager.Render.StartUse(this, renderHandle);
- }
- }
+ SetState(State_Component, true);
+ UpdateUse();
}
///
@@ -217,18 +351,32 @@ namespace MagicaCloth2
if (MagicaManager.IsPlaying() == false)
return;
- // 無効化
- SetState(State_Enable, false);
+ SetState(State_Component, false);
+ UpdateUse();
+ }
- // チーム無効化
- MagicaManager.Team.SetEnable(TeamId, false);
+ internal void UpdateUse()
+ {
+ // 有効状態判定
+ bool now = IsState(State_Component) && IsState(State_Verification);
- // レンダラー無効化
- if (renderHandleList != null)
+ // 切り替え
{
- foreach (int renderHandle in renderHandleList)
+ SetState(State_Enable, now);
+
+ // チーム
+ MagicaManager.Team.SetEnable(TeamId, now);
+
+ // レンダラー
+ if (renderHandleList != null)
{
- MagicaManager.Render.EndUse(this, renderHandle);
+ foreach (int renderHandle in renderHandleList)
+ {
+ if (now)
+ MagicaManager.Render.StartUse(this, renderHandle);
+ else
+ MagicaManager.Render.EndUse(this, renderHandle);
+ }
}
}
}
@@ -243,10 +391,11 @@ namespace MagicaCloth2
cloth.serializeData2.DataValidate();
// パラメータ変更(実行時のみ)
- if (Application.isPlaying)
+ if (MagicaManager.IsPlaying())
{
// ここでは変更フラグのみ立てる
- SetState(State_ParameterDirty, true);
+ //SetState(State_ParameterDirty, true);
+ MagicaManager.Team.parameterDirtyList.Add(this);
}
}
@@ -254,26 +403,25 @@ namespace MagicaCloth2
///
/// 構築を開始し完了後に自動実行する
///
- internal bool StartBuild()
+ internal bool StartRuntimeBuild()
{
// ビルド開始
// -コンポーネントが有効であること
// -初期化済みであること
// -ビルドがまだ実行されていないこと
- if (IsValid() && IsState(State_InitComplete) && IsState(State_Build) == false)
+ // -ベイクデータを利用しないこと
+ if (IsValid() && IsState(State_InitSuccess) && IsState(State_Build) == false && IsState(State_UsePreBuild) == false)
{
result.SetProcess();
SetState(State_Build, true);
- var _ = BuildAsync(cts.Token);
+ var _ = RuntimeBuildAsync(cts.Token);
return true;
}
else
{
- Develop.LogError($"Cloth build failure!: {cloth.name}");
-
- // ビルド完了イベント
- cloth?.OnBuildComplete?.Invoke(false);
-
+ if (result.IsError() == false)
+ result.SetError(Define.Result.CreateCloth_CanNotStart);
+ Develop.LogError($"Cloth runtime build failure! [{cloth.name}] : {result.GetResultString()}");
return false;
}
}
@@ -284,25 +432,42 @@ namespace MagicaCloth2
///
internal bool AutoBuild()
{
- if (IsState(State_DisableAutoBuild) == false)
- return StartBuild();
+ bool ret;
+ bool buildComplate = true;
+
+ if (IsState(State_DisableAutoBuild))
+ {
+ ret = false;
+ }
else
- return false;
+ {
+ if (IsState(State_UsePreBuild))
+ ret = PreBuildDataConstruction();
+ else
+ {
+ ret = StartRuntimeBuild();
+ if (ret)
+ buildComplate = false; // OnBuildCompleteはランタイム構築後に呼ばれる
+ }
+ }
+
+ // ビルド完了イベント
+ if (buildComplate)
+ cloth?.OnBuildComplete?.Invoke(cloth, ret);
+
+ return ret;
}
///
- /// 構築タスク
+ /// 実行時構築タスク
///
///
///
- async Task BuildAsync(CancellationToken ct)
+ async Task RuntimeBuildAsync(CancellationToken ct)
{
isBuild = true;
Develop.DebugLog($"Build start : {Name}");
result.SetProcess();
-#if MC2_DEBUG
- var span = new TimeSpan("Build Cloth");
-#endif
// 作成されたレンダラー情報
var renderMeshInfos = new List();
@@ -316,21 +481,54 @@ namespace MagicaCloth2
var sdata = cloth.SerializeData;
var sdata2 = cloth.GetSerializeData2();
+ // 少し時間を開けてから処理を開始する
+ await Task.Delay(5);
+ ct.ThrowIfCancellationRequested();
+
// 同期対象がいる場合は相手の一時停止カウンターを加算する
- if (cloth.SyncCloth)
+ if (cloth.SyncPartnerCloth)
{
- var sync = cloth.SyncCloth;
+ var sync = cloth.SyncPartnerCloth;
while (sync != cloth && sync != null)
{
sync.Process.IncrementSuspendCounter();
- sync = sync.SyncCloth;
+ sync = sync.SyncPartnerCloth;
}
}
- // ペイントマップデータの作成(これはメインスレッドでのみ作成可能)
+ // 頂点属性配列の利用確認
+ bool useManualVertexAttribute = false;
+ if (sdata.clothType == ClothType.MeshCloth && sdata2.vertexAttributeList != null && sdata2.vertexAttributeList.Count > 0)
+ {
+ // 頂点属性配列の検証
+ if (sdata2.vertexAttributeList.Count != renderHandleList.Count)
+ {
+ result.SetError(Define.Result.CreateCloth_VertexAttributeListCountMismatch);
+ throw new MagicaClothProcessingException();
+ }
+ for (int i = 0; i < renderHandleList.Count; i++)
+ {
+ var vertexAttributeArray = sdata2.vertexAttributeList[i];
+ if (vertexAttributeArray == null)
+ {
+ result.SetError(Define.Result.CreateCloth_VertexAttributeListIsNull);
+ throw new MagicaClothProcessingException();
+ }
+ int renderHandle = renderHandleList[i];
+ var renderData = MagicaManager.Render.GetRendererData(renderHandle);
+ if (renderData.setupData.vertexCount != vertexAttributeArray.Length)
+ {
+ result.SetError(Define.Result.CreateCloth_VertexAttributeListDataMismatch);
+ throw new MagicaClothProcessingException();
+ }
+ }
+ useManualVertexAttribute = true;
+ }
+
+ // ペイントマップデータの利用確認と作成(これはメインスレッドでのみ作成可能)
bool usePaintMap = false;
var paintMapDataList = new List();
- if (sdata.clothType == ClothType.MeshCloth && sdata.paintMode != ClothSerializeData.PaintMode.Manual)
+ if (sdata.clothType == ClothType.MeshCloth && sdata.paintMode != ClothSerializeData.PaintMode.Manual && useManualVertexAttribute == false)
{
var ret = GeneratePaintMapDataList(paintMapDataList);
Develop.DebugLog($"Generate paint map data list. {ret.GetResultString()}");
@@ -348,8 +546,8 @@ namespace MagicaCloth2
}
// セレクションデータ
- // ペイントマップ指定の場合は空で初期化
- SelectionData selectionData = usePaintMap ? new SelectionData() : sdata2.selectionData.Clone();
+ // ペイントマップ指定もしくは頂点属性指定の場合は空で初期化
+ SelectionData selectionData = (usePaintMap || useManualVertexAttribute) ? new SelectionData() : sdata2.selectionData.Clone();
// BoneCloth/BoneSpringでシリアライズ2にTransformと属性辞書がある場合はIDと属性の辞書に変換(スレッドではアクセスできないため)
Dictionary boneAttributeDict = null;
@@ -389,13 +587,8 @@ namespace MagicaCloth2
}
}
- // セレクションデータ
- // ペイントマップ指定の場合は空で初期化
- //SelectionData selectionData = usePaintMap ? new SelectionData() : sdata2.selectionData;
-
// セレクションデータの有無
bool isValidSelection = selectionData?.IsValid() ?? false;
- //Develop.Log($"セレクションデータの有無:{isValidSelection}");
// MeshCloth/BoneClothで処理が一部異なる
if (clothType == ClothType.MeshCloth)
@@ -421,7 +614,7 @@ namespace MagicaCloth2
renderMesh.result.SetProcess();
// import -------------------------------------------------
- renderMesh.ImportFrom(renderData);
+ renderMesh.ImportFrom(renderData, sdata.GetUvChannel());
if (renderMesh.IsError)
{
result.Merge(renderMesh.result);
@@ -430,8 +623,25 @@ namespace MagicaCloth2
Develop.DebugLog($"(IMPORT) {renderMesh}");
// selection ----------------------------------------------
- // MeshClothでペイントテクスチャ指定の場合はセレクションデータを生成する
SelectionData renderSelectionData = selectionData;
+
+ // MeshClothで頂点属性指定がある場合はセレクションデータを生成する
+ if (useManualVertexAttribute)
+ {
+ // セレクションデータ生成
+ var ret = GenerateSelectionDataFromVertexAttributeData(clothTransformRecord, renderMesh, sdata2.vertexAttributeList[i], out renderSelectionData);
+ Develop.DebugLog($"Generate selection from vertex attribute data. {ret.GetResultString()}");
+ if (ret.IsError())
+ {
+ result.Merge(ret);
+ throw new MagicaClothProcessingException();
+ }
+
+ // セレクションデータ結合
+ selectionData.Merge(renderSelectionData);
+ }
+
+ // MeshClothでペイントテクスチャ指定の場合はセレクションデータを生成する
if (usePaintMap)
{
// renderMeshからセレクションデータ生成
@@ -478,7 +688,10 @@ namespace MagicaCloth2
var info = new RenderMeshInfo();
//info.mixHash = mixHash;
info.renderHandle = renderHandle;
- info.renderMesh = renderMesh;
+ info.renderMeshContainer = new VirtualMeshContainer(renderMesh);
+ //info.renderMeshPositionAndNormalChunk = renderData.renderMeshPositionAndNormalChunk;
+ //info.renderMeshTangentChunk = renderData.renderMeshTangentChunk;
+ info.renderDataWorkIndex = renderData.renderDataWorkIndex;
renderMesh = null;
renderMeshInfos.Add(info);
}
@@ -488,7 +701,7 @@ namespace MagicaCloth2
{
// ■BoneCloth
// import
- proxyMesh.ImportFrom(boneClothSetupData);
+ proxyMesh.ImportFrom(boneClothSetupData, 0);
if (proxyMesh.IsError)
{
result.Merge(proxyMesh.result);
@@ -609,16 +822,6 @@ namespace MagicaCloth2
throw new MagicaClothProcessingException();
}
- //--------------------------------------------------------------------
-#if false
- // pitch/yaw個別制限はv1.0では実装しないので一旦停止
- // 角度制限計算用回転を作成
- ct.ThrowIfCancellationRequested();
- proxyMesh.CreateAngleCalcLocalRotation(normalCalculation, normalCalculationCenter);
- if (proxyMesh.IsError)
- throw new InvalidOperationException();
-#endif
-
//--------------------------------------------------------------------
// finish
ct.ThrowIfCancellationRequested();
@@ -637,7 +840,8 @@ namespace MagicaCloth2
foreach (var info in renderMeshInfos)
{
ct.ThrowIfCancellationRequested();
- var vmesh = info.renderMesh;
+ var cmesh = info.renderMeshContainer;
+ var vmesh = cmesh.shareVirtualMesh;
vmesh.Mapping(proxyMesh);
if (vmesh.IsError)
{
@@ -674,7 +878,7 @@ namespace MagicaCloth2
ct.ThrowIfCancellationRequested();
if (cloth == null)
throw new OperationCanceledException(); // キャンセル扱いにする
- var syncCloth = cloth.SyncCloth;
+ var syncCloth = cloth.SyncPartnerCloth;
if (syncCloth != null)
{
int timeOutCount = 100;
@@ -690,6 +894,7 @@ namespace MagicaCloth2
Develop.LogWarning($"Sync timeout! Is there a deadlock between synchronous cloths?");
}
}
+ Develop.DebugLog($"Sync complete : {Name}");
// ■メインスレッド
ct.ThrowIfCancellationRequested();
@@ -707,11 +912,7 @@ namespace MagicaCloth2
}
// パラメータ変更フラグ
- SetState(State_ParameterDirty, true);
-
- // 自チームと同期チームのデータ(コピー)
- //var teamData = MagicaManager.Team.GetTeamData(TeamId);
- //var syncTeamData = syncCloth != null ? MagicaManager.Team.GetTeamData(syncCloth.Process.TeamId) : default;
+ //SetState(State_ParameterDirty, true);
// ■スレッド
ct.ThrowIfCancellationRequested();
@@ -747,12 +948,6 @@ namespace MagicaCloth2
throw new MagicaClothProcessingException();
}
- // セルフコリジョン2(SelfCollision2)
- //ct.ThrowIfCancellationRequested();
- //self2ConstraintData = SelfCollisionConstraint2.CreateData(TeamId, teamData, ProxyMesh, parameters, syncCloth?.Process?.TeamId ?? 0, syncTeamData, syncCloth?.Process?.ProxyMesh);
- //if (self2ConstraintData != null && self2ConstraintData.result.IsError())
- // result = self2ConstraintData.result;
-
if (result.IsError())
throw new MagicaClothProcessingException();
}
@@ -782,7 +977,7 @@ namespace MagicaCloth2
lock (lockObject)
{
// ProxyMesh登録
- ProxyMesh = proxyMesh;
+ ProxyMeshContainer = new VirtualMeshContainer(proxyMesh);
proxyMesh = null;
// チーム登録
@@ -793,8 +988,11 @@ namespace MagicaCloth2
throw new MagicaClothProcessingException();
}
+ // パラメータ変更フラグ
+ MagicaManager.Team.parameterDirtyList.Add(this);
+
// プロキシメッシュ登録
- MagicaManager.VMesh.RegisterProxyMesh(TeamId, ProxyMesh);
+ MagicaManager.VMesh.RegisterProxyMesh(TeamId, ProxyMeshContainer);
MagicaManager.Simulation.RegisterProxyMesh(this);
// コライダー登録
@@ -812,23 +1010,20 @@ namespace MagicaCloth2
{
foreach (var info in renderMeshInfos)
{
- if (info.renderMesh.IsError == false && info.renderMesh.IsMapping)
+ var renderMesh = info.renderMeshContainer.shareVirtualMesh;
+
+ if (renderMesh.IsError == false && renderMesh.IsMapping)
{
// マッピングメッシュのデータ検証
// ここまでの時間経過でRendererが消滅しているなどの状況があり得るため
- if (info.renderMesh.IsValid())
+ if (renderMesh.IsValid())
{
// MappingMesh登録
- info.mappingChunk = MagicaManager.VMesh.RegisterMappingMesh(TeamId, info.renderMesh);
-
- // 完了
- info.renderMesh.result.SetSuccess();
-
- // コンポーネントがすでに有効状態ならば利用開始
- if (IsState(State_Enable))
- {
- MagicaManager.Render.StartUse(this, info.renderHandle);
- }
+ info.mappingChunk = MagicaManager.VMesh.RegisterMappingMesh(
+ TeamId,
+ info.renderMeshContainer,
+ info.renderDataWorkIndex
+ );
}
}
}
@@ -844,13 +1039,13 @@ namespace MagicaCloth2
ct.ThrowIfCancellationRequested();
// チームの有効状態の設定
- MagicaManager.Team.SetEnable(TeamId, IsState(State_Enable));
+ UpdateUse();
- // 初期化完了
+ // ビルド完了
result.SetSuccess();
SetState(State_Running, true);
- Develop.DebugLog($"Build Complate : {Name}");
+ Develop.DebugLog($"Build Complate : {Name}, TeamId:{TeamId}");
}
catch (MagicaClothProcessingException)
{
@@ -874,26 +1069,23 @@ namespace MagicaCloth2
// この時点でデータが存在する場合は失敗しているので破棄する
foreach (var info in renderMeshInfos)
{
- info?.renderMesh?.Dispose();
+ info?.renderMeshContainer?.Dispose();
}
proxyMesh?.Dispose();
// 同期対象がいる場合は相手の一時停止カウンターを減算する
- if (cloth != null && cloth.SyncCloth)
+ if (cloth != null && cloth.SyncPartnerCloth)
{
- var sync = cloth.SyncCloth;
+ var sync = cloth.SyncPartnerCloth;
while (sync != cloth && sync != null)
{
sync.Process.DecrementSuspendCounter();
- sync = sync.SyncCloth;
+ sync = sync.SyncPartnerCloth;
}
}
// ビルド完了
isBuild = false;
-#if MC2_DEBUG
- span.DebugLog();
-#endif
// この時点でコンポーネントが削除されている場合は破棄する
if (isDestory)
@@ -903,8 +1095,11 @@ namespace MagicaCloth2
}
else if (cloth != null)
{
+ if (result.IsFaild())
+ Develop.LogError($"Cloth runtime build failure! [{cloth.name}] : {result.GetResultString()}");
+
// ビルド完了イベント
- cloth.OnBuildComplete?.Invoke(result.IsSuccess());
+ cloth.OnBuildComplete?.Invoke(cloth, result.IsSuccess());
}
}
}
@@ -1112,22 +1307,247 @@ namespace MagicaCloth2
return result;
}
-
- //=========================================================================================
- // 単体マッピング
- // メモ
- // ・レンダラーの情報はすべてスレッドローカルで作成して処理する
- // ・成功した場合は最後に書き戻す
-
- //=========================================================================================
///
- /// コライダーの現在のローカルインデックスを返す
+ /// 頂点属性データ配列からセレクションデータを構築する
///
- ///
- /// (-1)存在しない
- internal int GetColliderIndex(ColliderComponent col)
+ ///
+ ///
+ ///
+ ///
+ ///
+ public ResultCode GenerateSelectionDataFromVertexAttributeData(
+ TransformRecord clothTransformRecord, VirtualMesh renderMesh, VertexAttribute[] vertexAttributeArray, out SelectionData selectionData
+ )
{
- return colliderList.IndexOf(col);
+ ResultCode result = new ResultCode();
+ result.SetProcess();
+ selectionData = new SelectionData();
+
+ try
+ {
+ // セレクションデータバッファ作成
+ int vcnt = renderMesh.VertexCount;
+ using var positionList = new NativeArray(vcnt, Allocator.TempJob);
+ //using var attributeList = new NativeArray(vcnt, Allocator.TempJob);
+
+ // 頂点座標をクロス空間に変換する
+ var toM = MathUtility.Transform(renderMesh.initLocalToWorld, clothTransformRecord.worldToLocalMatrix);
+ JobUtility.TransformPositionRun(renderMesh.localPositions.GetNativeArray(), positionList, vcnt, toM);
+
+ // セレクションデータ設定
+ selectionData.positions = positionList.ToArray();
+ selectionData.attributes = vertexAttributeArray; // 参照のみ
+ // 最大距離はプロキシメッシュの座標空間に変換する
+ selectionData.maxConnectionDistance = MathUtility.TransformDistance(renderMesh.maxVertexDistance.Value, toM);
+ //Develop.DebugLog($"GenerateSelectionDataFromPaintMap. maxConnectionDistance:{selectionData.maxConnectionDistance}, renderMesh.maxVertexDistance:{renderMesh.maxVertexDistance.Value}");
+ selectionData.userEdit = true;
+
+ result.SetSuccess();
+ }
+ catch (MagicaClothProcessingException)
+ {
+ if (result.IsNone()) result.SetError(Define.Result.CreateCloth_InvalidVertexAttributeData);
+ result.DebugLog();
+ }
+ catch (Exception e)
+ {
+ Debug.LogException(e);
+ result.SetError(Define.Result.CreateCloth_InvalidVertexAttributeData);
+ }
+
+ return result;
+ }
+
+ //=========================================================================================
+ static readonly ProfilerMarker preBuildProfiler = new ProfilerMarker("ClothProcess.PreBuild");
+ static readonly ProfilerMarker preBuildDeserializationProfiler = new ProfilerMarker("ClothProcess.PreBuild.Deserialization");
+ static readonly ProfilerMarker preBuildRegistrationProfiler = new ProfilerMarker("ClothProcess.PreBuild.Registration");
+
+ ///
+ /// PreBuildデータによる即時構築
+ ///
+ ///
+ internal bool PreBuildDataConstruction()
+ {
+ if (IsState(State_UsePreBuild) == false)
+ return false;
+ if (IsState(State_InitSuccess) == false)
+ return false;
+
+ // 構築開始
+ Develop.DebugLog($"Pre-Build start [{cloth.name}]");
+ preBuildProfiler.Begin();
+
+ result.SetProcess();
+ var sdata = cloth.SerializeData;
+ var sdata2 = cloth.GetSerializeData2();
+
+ VirtualMeshContainer proxyMeshContainer = null;
+ List renderMeshContainerList = new List();
+
+ try
+ {
+ // 固有部分データ
+ var uniquePreBuildData = sdata2.preBuildData.uniquePreBuildData;
+
+ // 共有部分データ
+ var preBuildDeserializeData = MagicaManager.PreBuild.GetPreBuildData(sdata2.preBuildData.GetSharePreBuildData());
+
+ try
+ {
+ preBuildDeserializationProfiler.Begin();
+
+ // ProxyMesh復元
+ proxyMeshContainer = new VirtualMeshContainer(preBuildDeserializeData.proxyMesh);
+ if (proxyMeshContainer.shareVirtualMesh.IsError)
+ {
+ result.Merge(proxyMeshContainer.shareVirtualMesh.result);
+ throw new MagicaClothProcessingException();
+ }
+ proxyMeshContainer.uniqueData = uniquePreBuildData.proxyMesh;
+
+ // RenderMesh復元
+ for (int i = 0; i < preBuildDeserializeData.renderMeshList.Count; i++)
+ {
+ var renderMeshContainer = new VirtualMeshContainer(preBuildDeserializeData.renderMeshList[i]);
+ renderMeshContainerList.Add(renderMeshContainer);
+ if (renderMeshContainer.shareVirtualMesh.IsError)
+ {
+ result.Merge(renderMeshContainer.shareVirtualMesh.result);
+ throw new MagicaClothProcessingException();
+ }
+ renderMeshContainer.uniqueData = uniquePreBuildData.renderMeshList[i];
+ }
+
+ // 制約データ復元
+ inertiaConstraintData = preBuildDeserializeData.inertiaConstraintData;
+ distanceConstraintData = preBuildDeserializeData.distanceConstraintData;
+ bendingConstraintData = preBuildDeserializeData.bendingConstraintData;
+ }
+ catch
+ {
+ throw;
+ }
+ finally
+ {
+ preBuildDeserializationProfiler.End();
+ }
+
+ // パラメータ変更フラグ
+ //SetState(State_ParameterDirty, true);
+
+ // 登録
+ try
+ {
+ preBuildRegistrationProfiler.Begin();
+
+ // ProxyMesh登録
+ ProxyMeshContainer = proxyMeshContainer;
+ proxyMeshContainer = null;
+
+ // チーム登録
+ TeamId = MagicaManager.Cloth.AddCloth(this, parameters);
+ if (TeamId <= 0)
+ {
+ result.SetError(Define.Result.ClothProcess_OverflowTeamCount4096);
+ throw new MagicaClothProcessingException();
+ }
+
+ // パラメータ変更フラグ
+ MagicaManager.Team.parameterDirtyList.Add(this);
+
+ // プロキシメッシュ登録
+ MagicaManager.VMesh.RegisterProxyMesh(TeamId, ProxyMeshContainer);
+ MagicaManager.Simulation.RegisterProxyMesh(this);
+
+ // コライダー登録
+ MagicaManager.Collider.Register(this);
+
+ // 制約データ登録
+ MagicaManager.Simulation.RegisterConstraint(this);
+
+ // マッピングメッシュ登録
+ for (int i = 0; i < renderMeshContainerList.Count; i++)
+ {
+ var renderMeshContainer = renderMeshContainerList[i];
+ var renderMesh = renderMeshContainer.shareVirtualMesh;
+ if (renderMesh.IsError == false && renderMesh.IsMapping && renderMesh.IsValid())
+ {
+ renderMeshContainerList[i] = null;
+
+ // レンダーハンドル
+ int renderHandle = renderHandleList[i];
+ var renderData = MagicaManager.Render.GetRendererData(renderHandle);
+
+ // MappingMesh登録
+ var mappingChunk = MagicaManager.VMesh.RegisterMappingMesh(
+ TeamId,
+ renderMeshContainer,
+ renderData.renderDataWorkIndex
+ );
+
+ // 完了
+ renderMesh.result.SetSuccess();
+
+ // レンダラー情報を登録
+ var info = new RenderMeshInfo()
+ {
+ renderHandle = renderHandle,
+ renderMeshContainer = renderMeshContainer,
+ mappingChunk = mappingChunk,
+ renderDataWorkIndex = renderData.renderDataWorkIndex
+ };
+ renderMeshInfoList.Add(info);
+ }
+ }
+
+ // チームの有効状態の設定
+ UpdateUse();
+ }
+ catch
+ {
+ throw;
+ }
+ finally
+ {
+ preBuildRegistrationProfiler.End();
+ }
+
+ // ビルド完了
+ result.SetSuccess();
+ SetState(State_Running, true);
+
+ Develop.DebugLog($"Pre-Build Complate : {Name}, TeamId:{TeamId}");
+ }
+ catch (MagicaClothProcessingException)
+ {
+ if (result.IsError() == false)
+ result.SetError(Define.Result.PreBuild_UnknownError);
+ result.DebugLog();
+ }
+ catch (Exception e)
+ {
+ Debug.LogException(e);
+ result.SetError(Define.Result.PreBuild_Exception);
+ }
+ finally
+ {
+ // この時点でデータが存在する場合は失敗しているので破棄する
+ renderMeshContainerList.ForEach(x => x?.Dispose());
+ renderMeshContainerList.Clear();
+ proxyMeshContainer?.Dispose();
+
+ // ビルド完了
+ //Develop.DebugLog($"PreBuild Construction Complate.[{cloth.name}] result:{result.GetResultString()}");
+ if (result.IsFaild())
+ Develop.LogError($"Cloth Pre-Build construction failure! [{cloth.name}] : {result.GetResultString()}");
+ else
+ Develop.DebugLog($"Cloth Pre-Build Success! [{cloth.name}]");
+ }
+
+ preBuildProfiler.End();
+
+ return result.IsSuccess();
}
//=========================================================================================
@@ -1140,18 +1560,19 @@ namespace MagicaCloth2
// 連動アニメーター更新
if (cullingSettings.cameraCullingMode == CullingSettings.CameraCullingMode.AnimatorLinkage
- || cullingSettings.cameraCullingMethod == CullingSettings.CameraCullingMethod.AutomaticRenderer)
+ || cullingSettings.cameraCullingMethod == CullingSettings.CameraCullingMethod.AutomaticRenderer
+ || cloth.SerializeData.updateMode == ClothUpdateMode.AnimatorLinkage)
{
- cullingAnimator = cloth.GetComponentInParent();
+ interlockingAnimator = cloth.GetComponentInParent();
}
// 連動レンダラー更新
- if (cullingSettings.cameraCullingMethod == CullingSettings.CameraCullingMethod.AutomaticRenderer && cullingAnimator)
+ if (cullingSettings.cameraCullingMethod == CullingSettings.CameraCullingMethod.AutomaticRenderer && interlockingAnimator)
{
// ★GetComponentsInChildrenのコストはキャラクタ100体で1msほど。
// ★もしコストが問題となるようならばキャッシュする
- cullingAnimatorRenderers.Clear();
- cullingAnimator.GetComponentsInChildren(cullingAnimatorRenderers);
+ interlockingAnimatorRenderers.Clear();
+ interlockingAnimator.GetComponentsInChildren(interlockingAnimatorRenderers);
}
}
@@ -1161,7 +1582,7 @@ namespace MagicaCloth2
internal void UpdateRendererUse()
{
// 対応するレンダーデータに更新を指示する
- renderHandleList.ForEach(handle => MagicaManager.Render.GetRendererData(handle).UpdateUse(null, 0));
+ renderHandleList.ForEach(handle => MagicaManager.Render.GetRendererData(handle).UpdateUse(this, 0));
}
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs.meta
index 39b3da10..5ea84a66 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcess.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs
index 6ccb7195..c0e04e64 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Threading;
using Unity.Collections;
+using Unity.Mathematics;
using UnityEngine;
namespace MagicaCloth2
@@ -16,20 +17,31 @@ namespace MagicaCloth2
{
public MagicaCloth cloth { get; internal set; }
+ ///
+ /// 同期中の参照クロス。これは同期階層の最上位のクロスを指す
+ ///
+ public MagicaCloth SyncTopCloth { get; internal set; }
+
///
/// 状態フラグ(0 ~ 31)
///
public const int State_Valid = 0;
public const int State_Enable = 1;
- public const int State_ParameterDirty = 2;
- public const int State_InitComplete = 3;
- public const int State_Build = 4;
- public const int State_Running = 5;
- public const int State_DisableAutoBuild = 6;
- public const int State_CullingInvisible = 7; // チームデータの同フラグのコピー
- public const int State_CullingKeep = 8; // チームデータの同フラグのコピー
- public const int State_SkipWriting = 9; // 書き込み停止(ストップモーション用)
- public const int State_SkipWritingDirty = 10; // 書き込み停止フラグ更新サイン
+ //public const int State_ParameterDirty = 2;
+ public const int State_InitSuccess = 3;
+ public const int State_InitComplete = 4;
+ public const int State_Build = 5;
+ public const int State_Running = 6;
+ public const int State_DisableAutoBuild = 7;
+ public const int State_CameraCullingInvisible = 8; // チームデータの同フラグのコピー
+ public const int State_CameraCullingKeep = 9; // チームデータの同フラグのコピー
+ public const int State_SkipWriting = 10; // 書き込み停止(ストップモーション用)
+ //public const int State_SkipWritingDirty = 11; // 書き込み停止フラグ更新サイン
+ public const int State_UsePreBuild = 12; // PreBuildを利用
+ public const int State_DistanceCullingInvisible = 13; // チームデータの同フラグのコピー
+ public const int State_UpdateTangent = 14; // 接線の更新
+ public const int State_Component = 15; // コンポーネントの有効状態
+ public const int State_Verification = 16; // 検証結果による有効状態
///
/// 現在の状態
@@ -45,7 +57,7 @@ namespace MagicaCloth2
/// レンダー情報へのハンドル
/// (レンダラーのセットアップデータ)
///
- List renderHandleList = new List();
+ internal List renderHandleList = new List();
///
/// BoneClothのセットアップデータ
@@ -58,8 +70,11 @@ namespace MagicaCloth2
public class RenderMeshInfo
{
public int renderHandle;
- public VirtualMesh renderMesh;
+ public VirtualMeshContainer renderMeshContainer;
public DataChunk mappingChunk;
+ //public DataChunk renderMeshPositionAndNormalChunk;
+ //public DataChunk renderMeshTangentChunk;
+ public int renderDataWorkIndex;
}
internal List renderMeshInfoList = new List();
@@ -96,6 +111,11 @@ namespace MagicaCloth2
internal ResultCode result;
public ResultCode Result => result;
+ ///
+ /// 初期化データ参照結果
+ ///
+ public ResultCode InitDataResult { get; internal set; }
+
///
/// Cloth Type
///
@@ -120,18 +140,15 @@ namespace MagicaCloth2
///
/// プロキシメッシュ
///
- public VirtualMesh ProxyMesh { get; private set; } = null;
+ public VirtualMeshContainer ProxyMeshContainer { get; private set; } = null;
///
- /// コライダーリスト
- /// コライダーが格納されるインデックスは他のデータのインデックスと一致している
+ /// 登録中のコライダー
+ /// int2 (メインコライダー・ローカルインデックス, シンメトリーコライダー・ローカルインデックス)
+ /// メインコライダーのインデックス0はあり得る
+ /// シンメトリーコライダーのインデックス0はシンメトリーが存在しないことを示す
///
- internal List colliderList = new List();
-
- ///
- /// コライダー配列数
- ///
- internal int ColliderCapacity => colliderList.Count;
+ internal Dictionary colliderDict = new Dictionary();
//=========================================================================================
///
@@ -156,14 +173,37 @@ namespace MagicaCloth2
//=========================================================================================
///
- /// カリング用対象アニメーター
+ /// 連動アニメーター
+ /// ・カリング
+ /// ・更新モード
///
- internal Animator cullingAnimator = null;
+ internal Animator interlockingAnimator = null;
///
/// カリング用アニメーター配下のレンダラーリスト
///
- internal List cullingAnimatorRenderers = new List();
+ internal List interlockingAnimatorRenderers = new List();
+
+ ///
+ /// 現在アンカーとして設定されているTransformのインスタンスID
+ ///
+ internal int anchorTransformId = 0;
+
+ ///
+ /// 現在距離カリングの参照として設定されているオブジェクトのインスタンスID
+ ///
+ internal int distanceReferenceObjectId = 0;
+
+ ///
+ /// コンポーネントの登録TransformIndex
+ /// tdata.componentTransformIndexのコピー
+ ///
+ //internal int componentTransformIndex = 0;
+
+ internal Animator cameraCullingAnimator = null;
+ internal List cameraCullingRenderers = null;
+ internal CullingSettings.CameraCullingMode cameraCullingMode;
+ internal bool cameraCullingOldInvisible = false;
//=========================================================================================
///
@@ -171,12 +211,12 @@ namespace MagicaCloth2
///
CancellationTokenSource cts = new CancellationTokenSource();
volatile object lockObject = new object();
- volatile object lockState = new object();
+ //volatile object lockState = new object();
///
/// 初期化待機カウンター
///
- volatile int suspendCounter = 0;
+ //volatile int suspendCounter = 0;
///
/// 破棄フラグ
@@ -195,7 +235,7 @@ namespace MagicaCloth2
public BitField32 GetStateFlag()
{
- lock (lockState)
+ //lock (lockState)
{
// copy
var state = stateFlag;
@@ -205,7 +245,7 @@ namespace MagicaCloth2
public bool IsState(int state)
{
- lock (lockState)
+ //lock (lockState)
{
return stateFlag.IsSet(state);
}
@@ -213,16 +253,19 @@ namespace MagicaCloth2
public void SetState(int state, bool sw)
{
- lock (lockState)
+ //lock (lockState)
{
stateFlag.SetBits(state, sw);
}
}
public bool IsValid() => IsState(State_Valid);
- public bool IsCullingInvisible() => IsState(State_CullingInvisible);
- public bool IsCullingKeep() => IsState(State_CullingKeep);
+ public bool IsRunning() => IsState(State_Running);
+ public bool IsCameraCullingInvisible() => IsState(State_CameraCullingInvisible);
+ public bool IsCameraCullingKeep() => IsState(State_CameraCullingKeep);
+ public bool IsDistanceCullingInvisible() => IsState(State_DistanceCullingInvisible);
public bool IsSkipWriting() => IsState(State_SkipWriting);
+ public bool IsUpdateTangent() => IsState(State_UpdateTangent);
public bool IsEnable
{
@@ -240,7 +283,7 @@ namespace MagicaCloth2
{
if (IsValid() == false || TeamId == 0)
return false;
- return ProxyMesh?.IsSuccess ?? false;
+ return ProxyMeshContainer?.shareVirtualMesh?.IsSuccess ?? false;
}
}
@@ -292,7 +335,7 @@ namespace MagicaCloth2
continue;
// 仮想メッシュ破棄
- info.renderMesh?.Dispose();
+ info.renderMeshContainer?.Dispose();
}
renderMeshInfoList.Clear();
renderMeshInfoList = null;
@@ -310,13 +353,24 @@ namespace MagicaCloth2
boneClothSetupData = null;
// プロキシメッシュ破棄
- ProxyMesh?.Dispose();
- ProxyMesh = null;
+ ProxyMeshContainer?.Dispose();
+ ProxyMeshContainer = null;
- colliderList.Clear();
+ colliderDict.Clear();
- cullingAnimator = null;
- cullingAnimatorRenderers.Clear();
+ interlockingAnimator = null;
+ interlockingAnimatorRenderers.Clear();
+
+ // PreBuildデータ解除
+ MagicaManager.PreBuild?.UnregisterPreBuildData(cloth?.GetSerializeData2()?.preBuildData.GetSharePreBuildData());
+
+ // 作業バッファ破棄
+ SyncTopCloth = null;
+ int compId = cloth.GetInstanceID();
+ MagicaManager.Team?.comp2SuspendCounterMap.Remove(compId);
+ MagicaManager.Team?.comp2TeamIdMap.Remove(compId);
+ MagicaManager.Team?.comp2SyncPartnerCompMap.Remove(compId);
+ MagicaManager.Team?.comp2SyncTopCompMap.Remove(compId);
// 完全破棄フラグ
isDestoryInternal = true;
@@ -324,28 +378,49 @@ namespace MagicaCloth2
Develop.DebugLog($"Cloth dispose internal.");
// 破棄監視リストから削除する
- MagicaManager.Team.RemoveMonitoringProcess(this);
+ MagicaManager.Team?.RemoveMonitoringProcess(this);
}
internal void IncrementSuspendCounter()
{
- lock (lockObject)
+ //suspendCounter++;
+ var tm = MagicaManager.Team;
+ int compId = cloth.GetInstanceID();
+ if (tm.comp2SuspendCounterMap.TryGetValue(compId, out int cnt))
{
- suspendCounter++;
+ cnt++;
+ //tm.comp2SuspendCounterMap.Add(compId, cnt);
+ tm.comp2SuspendCounterMap[compId] = cnt;
}
+ else
+ tm.comp2SuspendCounterMap.Add(compId, 1);
}
internal void DecrementSuspendCounter()
{
- lock (lockObject)
+ //suspendCounter--;
+ var tm = MagicaManager.Team;
+ int compId = cloth.GetInstanceID();
+ if (tm.comp2SuspendCounterMap.TryGetValue(compId, out int cnt))
{
- suspendCounter--;
+ cnt--;
+ if (cnt > 0)
+ //tm.comp2SuspendCounterMap.Add(compId, cnt);
+ tm.comp2SuspendCounterMap[compId] = cnt;
+ else
+ tm.comp2SuspendCounterMap.Remove(compId);
}
}
internal int GetSuspendCounter()
{
- return suspendCounter;
+ //return suspendCounter;
+ var tm = MagicaManager.Team;
+ int compId = cloth.GetInstanceID();
+ if (tm.comp2SuspendCounterMap.TryGetValue(compId, out int cnt))
+ return cnt;
+ else
+ return 0;
}
public RenderMeshInfo GetRenderMeshInfo(int index)
@@ -364,16 +439,22 @@ namespace MagicaCloth2
public void GetUsedTransform(HashSet transformSet)
{
cloth.SerializeData.GetUsedTransform(transformSet);
+ cloth.serializeData2.GetUsedTransform(transformSet);
clothTransformRecord?.GetUsedTransform(transformSet);
boneClothSetupData?.GetUsedTransform(transformSet);
renderHandleList.ForEach(handle => MagicaManager.Render.GetRendererData(handle).GetUsedTransform(transformSet));
customSkinningBoneRecords.ForEach(rd => rd.GetUsedTransform(transformSet));
normalAdjustmentTransformRecord?.GetUsedTransform(transformSet);
+
+ // nullを除外する
+ if (transformSet.Contains(null))
+ transformSet.Remove(null);
}
public void ReplaceTransform(Dictionary replaceDict)
{
cloth.SerializeData.ReplaceTransform(replaceDict);
+ cloth.serializeData2.ReplaceTransform(replaceDict);
clothTransformRecord?.ReplaceTransform(replaceDict);
boneClothSetupData?.ReplaceTransform(replaceDict);
renderHandleList.ForEach(handle => MagicaManager.Render.GetRendererData(handle).ReplaceTransform(replaceDict));
@@ -386,7 +467,44 @@ namespace MagicaCloth2
// ここではフラグのみ更新する
// 実際の更新はチームのAlwaysTeamUpdate()で行われる
SetState(State_SkipWriting, sw);
- SetState(State_SkipWritingDirty, true);
+ //SetState(State_SkipWritingDirty, true);
+ MagicaManager.Team.skipWritingDirtyList.Add(this);
+ }
+
+ internal ClothUpdateMode GetClothUpdateMode()
+ {
+ switch (cloth.SerializeData.updateMode)
+ {
+ case ClothUpdateMode.Normal:
+ case ClothUpdateMode.UnityPhysics:
+ case ClothUpdateMode.Unscaled:
+ return cloth.SerializeData.updateMode;
+ case ClothUpdateMode.AnimatorLinkage:
+ if (interlockingAnimator)
+ {
+ switch (interlockingAnimator.updateMode)
+ {
+ case AnimatorUpdateMode.Normal:
+ return ClothUpdateMode.Normal;
+#if UNITY_2023_1_OR_NEWER
+ case AnimatorUpdateMode.Fixed:
+ return ClothUpdateMode.UnityPhysics;
+#else
+ case AnimatorUpdateMode.AnimatePhysics:
+ return ClothUpdateMode.UnityPhysics;
+#endif
+ case AnimatorUpdateMode.UnscaledTime:
+ return ClothUpdateMode.Unscaled;
+ default:
+ Develop.DebugLogWarning($"[{cloth.name}] Unknown Animator UpdateMode:{interlockingAnimator.updateMode}");
+ break;
+ }
+ }
+ return ClothUpdateMode.Normal;
+ default:
+ Develop.LogError($"[{cloth.name}] Unknown Cloth Update Mode:{cloth.SerializeData.updateMode}");
+ return ClothUpdateMode.Normal;
+ }
}
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs.meta
index 5ac7149c..846c46ef 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessData.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs
index 6f68534a..0d69d07d 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs
@@ -1,13 +1,56 @@
// Magica Cloth 2.
// Copyright (c) 2023 MagicaSoft.
// https://magicasoft.jp
-
using Unity.Mathematics;
+using UnityEngine;
namespace MagicaCloth2
{
public partial class ClothProcess
{
+ public ResultCode GenerateStatusCheck()
+ {
+ ResultCode result = new ResultCode();
+
+ // スケール値チェック
+ var scl = cloth.transform.lossyScale;
+ if (Mathf.Approximately(scl.x, 0.0f) || Mathf.Approximately(scl.y, 0.0f) || Mathf.Approximately(scl.z, 0.0f))
+ {
+ // スケール値がゼロ
+ result.SetError(Define.Result.Init_ScaleIsZero);
+ }
+ else if (scl.x < 0.0f || scl.y < 0.0f || scl.z < 0.0f)
+ {
+ // 負のスケール
+ // 負のスケールでの初期化は、事前構築もしくは初期化データありの場合許可する
+ var sdata2 = cloth.GetSerializeData2();
+ if (sdata2.preBuildData.UsePreBuild() || (sdata2.initData?.HasData() ?? false))
+ {
+ // ただし許可されるのは一軸フリップのみ
+ int flipCount = (scl.x < 0.0f ? 1 : 0) + (scl.y < 0.0f ? 1 : 0) + (scl.z < 0.0f ? 1 : 0);
+ if (flipCount != 1)
+ {
+ result.SetError(Define.Result.Init_NegativeScale);
+ }
+ }
+ else
+ result.SetError(Define.Result.Init_NegativeScale);
+ }
+ else
+ {
+ float diff1 = Mathf.Abs(1.0f - scl.x / scl.y);
+ float diff2 = Mathf.Abs(1.0f - scl.x / scl.z);
+ const float diffTolerance = 0.01f; // 誤差(1%)
+ if (diff1 > diffTolerance || diff2 > diffTolerance)
+ {
+ // 一様スケールではない
+ result.SetWarning(Define.Result.Init_NonUniformScale);
+ }
+ }
+
+ return result;
+ }
+
internal bool GenerateInitialization()
{
result.SetProcess();
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs.meta
index 9c9fc9ed..a74da22e 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothProcessGeneration.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs
index d37aef77..209cb672 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs
@@ -29,6 +29,13 @@ namespace MagicaCloth2
///
public List sourceRenderers = new List();
+ ///
+ /// Write target to mesh in MeshCloth.
+ /// [OK] Runtime changes.
+ /// [NG] Export/Import with Presets
+ ///
+ public ClothMeshWriteMode meshWriteMode = ClothMeshWriteMode.PositionAndNormal;
+
public enum PaintMode
{
Manual = 0,
@@ -55,6 +62,14 @@ namespace MagicaCloth2
///
public List paintMaps = new List();
+ ///
+ /// The UV channel that references the paint map.
+ /// [NG] Runtime changes.
+ /// [NG] Export/Import with Presets
+ ///
+ [Range(0, 7)]
+ public int paintMapUvChannel = 0;
+
///
/// Root bone list used in BoneCloth.
/// [NG] Runtime changes.
@@ -92,7 +107,7 @@ namespace MagicaCloth2
/// [OK] Runtime changes.
/// [NG] Export/Import with Presets
///
- public ClothUpdateMode updateMode = ClothUpdateMode.Normal;
+ public ClothUpdateMode updateMode = ClothUpdateMode.AnimatorLinkage;
///
/// Blend ratio between initial pose and animation pose.
@@ -180,7 +195,7 @@ namespace MagicaCloth2
/// [OK] Runtime changes.
/// [NG] Export/Import with Presets
///
- [System.NonSerialized]
+ [Range(0.0f, 1.0f)]
public float blendWeight = 1.0f;
///
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs.meta
index 09004c49..cac805ce 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs
index 93fb8e38..fda9bd42 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs
@@ -11,8 +11,14 @@ namespace MagicaCloth2
/// Parts that cannot be exported externally.
///
[System.Serializable]
- public class ClothSerializeData2 : IDataValidate, IValid
+ public class ClothSerializeData2 : IDataValidate, IValid, ITransform
{
+ ///
+ /// Initialization Data.
+ ///
+ [SerializeField]
+ public ClothInitSerializeData initData = new ClothInitSerializeData();
+
///
/// 頂点ペイントデータ
/// vertex paint data.
@@ -26,8 +32,23 @@ namespace MagicaCloth2
/// Transform and vertex attribute dictionary data.
/// When creating BoneCloth/BoneSpring at runtime, you can store Transform and vertex attribute pairs in this dictionary and use it instead of vertex paint data.
///
+ [System.NonSerialized]
public Dictionary boneAttributeDict = new Dictionary();
+ ///
+ /// Rendererに対応する頂点属性データ
+ /// 実行時にMeshClothを構築する場合に、このリストにレンダラーごとのメッシュ頂点数分の頂点属性を格納することでセレクションデータの代わりにすることができます
+ /// Vertex attribute data corresponding to the Renderer.
+ /// When constructing MeshCloth at runtime, you can substitute selection data by storing vertex attributes in this list for the number of mesh vertices per renderer.
+ ///
+ [System.NonSerialized]
+ public List vertexAttributeList = new List();
+
+ ///
+ /// PreBuild Data.
+ ///
+ public PreBuildSerializeData preBuildData = new PreBuildSerializeData();
+
//=========================================================================================
public ClothSerializeData2()
{
@@ -57,5 +78,17 @@ namespace MagicaCloth2
int hash = 0;
return hash;
}
+
+ public void GetUsedTransform(HashSet transformSet)
+ {
+ initData.GetUsedTransform(transformSet);
+ preBuildData.GetUsedTransform(transformSet);
+ }
+
+ public void ReplaceTransform(Dictionary replaceDict)
+ {
+ initData.ReplaceTransform(replaceDict);
+ preBuildData.ReplaceTransform(replaceDict);
+ }
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs.meta
index 66f53c6f..256f9c3d 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeData2.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs
index 55970226..42c3a5e6 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs
@@ -44,6 +44,11 @@ namespace MagicaCloth2
return false;
if (rootBones.Count(x => x != null) == 0)
return false;
+ if (rootBones.Distinct().Count() != rootBones.Count)
+ {
+ verificationResult.SetError(Define.Result.SerializeData_DuplicateRootBone);
+ return false;
+ }
break;
case ClothProcess.ClothType.MeshCloth:
if (sourceRenderers == null || sourceRenderers.Count == 0)
@@ -57,6 +62,11 @@ namespace MagicaCloth2
verificationResult.SetError(Define.Result.SerializeData_Over31Renderers);
return false;
}
+ if (sourceRenderers.Distinct().Count() != sourceRenderers.Count)
+ {
+ verificationResult.SetError(Define.Result.SerializeData_DuplicateRenderer);
+ return false;
+ }
break;
default:
return false;
@@ -107,10 +117,12 @@ namespace MagicaCloth2
///
public override int GetHashCode()
{
+ const int NullHash = -3910836;
+
int hash = 0;
hash += (int)clothType;
foreach (var ren in sourceRenderers)
- hash += ren?.GetInstanceID() ?? 0;
+ hash += ren?.GetInstanceID() ?? NullHash;
foreach (var t in rootBones)
{
var stack = new Stack(30);
@@ -119,7 +131,10 @@ namespace MagicaCloth2
{
var t2 = stack.Pop();
if (t2 == null)
+ {
+ hash += NullHash;
continue;
+ }
hash += t2.GetInstanceID();
hash += t2.localPosition.GetHashCode();
hash += t2.localRotation.GetHashCode();
@@ -142,6 +157,7 @@ namespace MagicaCloth2
hash += map.isReadable ? 1 : 0;
}
}
+ hash += paintMapUvChannel * 123;
hash += colliderCollisionConstraint.GetHashCode();
return hash;
@@ -158,7 +174,7 @@ namespace MagicaCloth2
//cparams.solverFrequency = Define.System.SolverFrequency;
cparams.gravity = clothType == ClothProcess.ClothType.BoneSpring ? 0.0f : gravity; // BoneSpring has no gravity.
- cparams.gravityDirection = gravityDirection;
+ cparams.worldGravityDirection = gravityDirection;
cparams.gravityFalloff = gravityFalloff;
cparams.stablizationTimeAfterReset = stablizationTimeAfterReset;
cparams.blendWeight = blendWeight;
@@ -169,6 +185,7 @@ namespace MagicaCloth2
cparams.rotationalInterpolation = rotationalInterpolation;
cparams.rootRotation = rootRotation;
+ cparams.culling.Convert(cullingSettings);
cparams.inertiaConstraint.Convert(inertiaConstraint);
cparams.tetherConstraint.Convert(tetherConstraint, clothType);
cparams.distanceConstraint.Convert(distanceConstraint, clothType);
@@ -187,8 +204,10 @@ namespace MagicaCloth2
{
ClothProcess.ClothType clothType;
List sourceRenderers;
+ ClothMeshWriteMode meshWriteMode;
PaintMode paintMode;
List paintMaps;
+ int paintMapUvChannel;
List rootBones;
RenderSetupData.BoneConnectionMode connectionMode;
float rotationalInterpolation;
@@ -204,9 +223,9 @@ namespace MagicaCloth2
MagicaCloth synchronization;
float stablizationTimeAfterReset;
float blendWeight;
- CullingSettings.CameraCullingMode cullingMode;
- CullingSettings.CameraCullingMethod cullingMethod;
- List cullingRenderers;
+ CullingSettings cullingSetting;
+ Transform anchor;
+ float anchorInertia;
internal TempBuffer(ClothSerializeData sdata)
{
@@ -217,8 +236,10 @@ namespace MagicaCloth2
{
clothType = sdata.clothType;
sourceRenderers = new List(sdata.sourceRenderers);
+ meshWriteMode = sdata.meshWriteMode;
paintMode = sdata.paintMode;
paintMaps = new List(sdata.paintMaps);
+ paintMapUvChannel = sdata.paintMapUvChannel;
rootBones = new List(sdata.rootBones);
connectionMode = sdata.connectionMode;
rotationalInterpolation = sdata.rotationalInterpolation;
@@ -234,17 +255,19 @@ namespace MagicaCloth2
synchronization = sdata.selfCollisionConstraint.syncPartner;
stablizationTimeAfterReset = sdata.stablizationTimeAfterReset;
blendWeight = sdata.blendWeight;
- cullingMode = sdata.cullingSettings.cameraCullingMode;
- cullingMethod = sdata.cullingSettings.cameraCullingMethod;
- cullingRenderers = new List(sdata.cullingSettings.cameraCullingRenderers);
+ cullingSetting = sdata.cullingSettings.Clone();
+ anchor = sdata.inertiaConstraint.anchor;
+ anchorInertia = sdata.inertiaConstraint.anchorInertia;
}
internal void Pop(ClothSerializeData sdata)
{
sdata.clothType = clothType;
sdata.sourceRenderers = sourceRenderers;
+ sdata.meshWriteMode = meshWriteMode;
sdata.paintMode = paintMode;
sdata.paintMaps = paintMaps;
+ sdata.paintMapUvChannel = paintMapUvChannel;
sdata.rootBones = rootBones;
sdata.connectionMode = connectionMode;
sdata.rotationalInterpolation = rotationalInterpolation;
@@ -260,9 +283,9 @@ namespace MagicaCloth2
sdata.selfCollisionConstraint.syncPartner = synchronization;
sdata.stablizationTimeAfterReset = stablizationTimeAfterReset;
sdata.blendWeight = blendWeight;
- sdata.cullingSettings.cameraCullingMode = cullingMode;
- sdata.cullingSettings.cameraCullingMethod = cullingMethod;
- sdata.cullingSettings.cameraCullingRenderers = cullingRenderers;
+ sdata.cullingSettings = cullingSetting;
+ sdata.inertiaConstraint.anchor = anchor;
+ sdata.inertiaConstraint.anchorInertia = anchorInertia;
}
}
@@ -325,6 +348,7 @@ namespace MagicaCloth2
sourceRenderers = new List(sdata.sourceRenderers);
paintMode = sdata.paintMode;
paintMaps = new List(sdata.paintMaps);
+ paintMapUvChannel = sdata.paintMapUvChannel;
rootBones = new List(sdata.rootBones);
connectionMode = sdata.connectionMode;
rotationalInterpolation = sdata.rotationalInterpolation;
@@ -404,5 +428,17 @@ namespace MagicaCloth2
///
///
public bool IsBoneSpring() => clothType == ClothProcess.ClothType.BoneSpring;
+
+ public int GetUvChannel()
+ {
+ switch (paintMode)
+ {
+ case PaintMode.Texture_Fixed_Move:
+ case PaintMode.Texture_Fixed_Move_Limit:
+ return paintMapUvChannel;
+ default:
+ return 0;
+ }
+ }
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs.meta
index 4e391e4b..e658b794 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothSerializeDataFunction.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs
index 47334c31..111d9366 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs
@@ -23,5 +23,14 @@ namespace MagicaCloth2
/// Updates are independent of Unity's Time.timeScale.
///
Unscaled = 2,
+
+ ///
+ /// Automatically set from linked animator.
+ /// 連動アニメーターから自動設定する
+ /// - Animator.UpdateMode.Normal -> Normal
+ /// - Animator.UpdateMode.AnimatePhysics -> UnityPhysics
+ /// - Animator.UpdateMode.UnscaledTime -> Unscaled
+ ///
+ AnimatorLinkage = 10,
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs.meta
index fd9986f0..970829f6 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/ClothUpdateMode.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs
index 195ff59e..927ec2b4 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs
@@ -2,11 +2,12 @@
// Copyright (c) 2023 MagicaSoft.
// https://magicasoft.jp
using System.Collections.Generic;
+using System.Linq;
using UnityEngine;
namespace MagicaCloth2
{
- public abstract class ColliderComponent : ClothBehaviour, IDataValidate
+ public abstract class ColliderComponent : ClothBehaviour, IDataValidate, ITransform
{
///
/// トランスフォームからの中心ローカルオフセット
@@ -23,6 +24,17 @@ namespace MagicaCloth2
[SerializeField]
protected Vector3 size;
+ ///
+ /// シンメトリーモード
+ /// Symmetry mode.
+ ///
+ public ColliderSymmetryMode symmetryMode = ColliderSymmetryMode.None;
+
+ ///
+ /// シンメトリーの接続対象
+ /// Symmetry connection target.
+ ///
+ public Transform symmetryTarget = null;
//=========================================================================================
///
@@ -42,6 +54,16 @@ namespace MagicaCloth2
///
private HashSet teamIdSet = new HashSet();
+ ///
+ /// 現在登録中のシンメトリーモード
+ ///
+ public ColliderSymmetryMode? ActiveSymmetryMode { get; private set; } = null;
+
+ ///
+ /// 現在登録中のシンメトリーターゲット
+ ///
+ public Transform ActiveSymmetryTarget { get; private set; }
+
//=========================================================================================
///
/// Get collider size.
@@ -52,26 +74,30 @@ namespace MagicaCloth2
///
///
///
- public virtual Vector3 GetSize()
- {
- return size;
- }
+ public virtual Vector3 GetSize() => size;
- public void SetSize(Vector3 size)
- {
- this.size = size;
- }
+ public void SetSize(Vector3 size) => this.size = size;
+
+ public void SetSizeX(float size) => this.size.x = size;
+ public void SetSizeY(float size) => this.size.y = size;
+ public void SetSizeZ(float size) => this.size.z = size;
///
/// スケール値を取得
///
///
- public float GetScale()
+ public virtual float GetScale()
{
// X軸のみを見る
return transform.lossyScale.x;
}
+ ///
+ /// 方向の逆転(基本的にカプセルコライダー用)
+ ///
+ ///
+ public virtual bool IsReverseDirection() => false;
+
///
/// チームへのコライダー登録通知
///
@@ -85,9 +111,11 @@ namespace MagicaCloth2
/// チームからのコライダー解除通知
///
///
- internal void Exit(int teamId)
+ /// 利用者0ならtrue
+ internal bool Exit(int teamId)
{
teamIdSet.Remove(teamId);
+ return teamIdSet.Count == 0;
}
///
@@ -101,15 +129,269 @@ namespace MagicaCloth2
// パラメータの検証
DataValidate();
+ // Symmetry更新
+ // シンメトリーは削除もしくは追加がある。またTransformが変更される場合もある
+ var oldActiveSymmetryMode = ActiveSymmetryMode;
+ var oldActiveSymmetryTarget = ActiveSymmetryTarget;
+ SetActiveSymmetryMode(firstOnly: false); // 最新の状態に更新
+ bool changeSymmetry = oldActiveSymmetryMode != ActiveSymmetryMode || oldActiveSymmetryTarget != ActiveSymmetryTarget;
+
+ // 反映
foreach (int teamId in teamIdSet)
{
- MagicaManager.Collider.UpdateParameters(this, teamId);
+ MagicaManager.Collider.UpdateParameters(this, teamId, changeSymmetry);
+ }
+ }
+
+ ///
+ /// 現在の状態から適切なシンメトリーモードとそのターゲットTransformを計算して返す
+ ///
+ ///
+ public ColliderSymmetryMode CalcSymmetryMode(out Transform symmetryParent)
+ {
+ symmetryParent = symmetryTarget;
+
+ // 親
+ var parent = transform.parent;
+ if (parent == null)
+ return ColliderSymmetryMode.None;
+
+ switch (symmetryMode)
+ {
+ case ColliderSymmetryMode.None:
+ return ColliderSymmetryMode.None;
+ case ColliderSymmetryMode.AutomaticHumanBody:
+ case ColliderSymmetryMode.AutomaticTarget:
+ break;
+ case ColliderSymmetryMode.X_Symmetry:
+ case ColliderSymmetryMode.Y_Symmetry:
+ case ColliderSymmetryMode.Z_Symmetry:
+ case ColliderSymmetryMode.XYZ_Symmetry:
+ // ターゲットnullの場合は親
+ if (symmetryParent == null)
+ symmetryParent = parent;
+ return symmetryMode;
+ default:
+ Develop.LogError("Unknown symmetry mode.");
+ return ColliderSymmetryMode.None;
+ }
+
+ // Automatic
+ Animator ani = symmetryMode == ColliderSymmetryMode.AutomaticHumanBody ? gameObject.GetComponentInParent(true) : null;
+
+ // 対象Transform
+ // AutomaticではSymmetryTargetは無視される
+ var target = symmetryMode == ColliderSymmetryMode.AutomaticTarget ? symmetryTarget : null;
+ if (target == null && ani)
+ {
+ // 自動判定
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.Hips, HumanBodyBones.Hips);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.LeftUpperLeg, HumanBodyBones.RightUpperLeg);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.RightUpperLeg, HumanBodyBones.LeftUpperLeg);
+
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.LeftLowerLeg, HumanBodyBones.RightLowerLeg);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.RightLowerLeg, HumanBodyBones.LeftLowerLeg);
+
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.LeftFoot, HumanBodyBones.RightFoot);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.RightFoot, HumanBodyBones.LeftFoot);
+
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.Spine, HumanBodyBones.Spine);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.Chest, HumanBodyBones.Chest);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.Neck, HumanBodyBones.Neck);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.Head, HumanBodyBones.Head);
+
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.LeftShoulder, HumanBodyBones.RightShoulder);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.RightShoulder, HumanBodyBones.LeftShoulder);
+
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.LeftUpperArm, HumanBodyBones.RightUpperArm);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.RightUpperArm, HumanBodyBones.LeftUpperArm);
+
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.LeftLowerArm, HumanBodyBones.RightLowerArm);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.RightLowerArm, HumanBodyBones.LeftLowerArm);
+
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.LeftHand, HumanBodyBones.RightHand);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.RightHand, HumanBodyBones.LeftHand);
+
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.LeftToes, HumanBodyBones.RightToes);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.RightToes, HumanBodyBones.LeftToes);
+
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.Jaw, HumanBodyBones.Jaw);
+ GetHumanoidSymmetryBone(ref target, parent, ani, HumanBodyBones.UpperChest, HumanBodyBones.UpperChest);
+ }
+ if (target == null)
+ target = parent;
+ symmetryParent = target;
+
+ // 親が同一かどうか
+ bool sameParent = target == parent;
+
+ // 各軸
+ var x = parent.right;
+ var y = parent.up;
+ var z = parent.forward;
+ var sx = target.right;
+ var sy = target.up;
+ var sz = target.forward;
+
+ // ベクトルの方向性情報
+ // Animatorがある場合はAnimatorから、ない場合は共通の親Transformから、それでも無い場合はワールドX軸
+ Vector3 H = Vector3.right;
+ if (ani)
+ H = ani.transform.right;
+ else
+ {
+ var commonParent = FindCommonParent(transform, symmetryParent);
+ if (commonParent)
+ {
+ //Debug.Log($"Find common parent:{commonParent.name}");
+ H = commonParent.right;
+ }
+ }
+
+ float xdot = Mathf.Abs(Vector3.Dot(H, x));
+ float ydot = Mathf.Abs(Vector3.Dot(H, y));
+ float zdot = Mathf.Abs(Vector3.Dot(H, z));
+
+ bool xsign = Vector3.Dot(x, sx) >= 0.0f;
+ bool ysign = Vector3.Dot(y, sy) >= 0.0f;
+ bool zsign = Vector3.Dot(z, sz) >= 0.0f;
+
+ if (xdot > ydot && xdot > zdot)
+ {
+ // (X)
+ if (sameParent)
+ return ColliderSymmetryMode.X_Symmetry;
+ if (Vector3.Dot(H, x) * Vector3.Dot(H, sx) > 0.0f)
+ {
+ if (ysign == false && zsign == false)
+ return ColliderSymmetryMode.XYZ_Symmetry;
+ else
+ return ColliderSymmetryMode.X_Symmetry;
+ }
+ else if (zsign)
+ return ColliderSymmetryMode.Y_Symmetry;
+ else
+ return ColliderSymmetryMode.Z_Symmetry;
+ }
+ else if (ydot > xdot && ydot > zdot)
+ {
+ // (Y)
+ if (sameParent)
+ return ColliderSymmetryMode.Y_Symmetry;
+ if (Vector3.Dot(H, y) * Vector3.Dot(H, sy) > 0.0f)
+ {
+ if (xsign == false && zsign == false)
+ return ColliderSymmetryMode.XYZ_Symmetry;
+ else
+ return ColliderSymmetryMode.Y_Symmetry;
+ }
+ else if (zsign)
+ return ColliderSymmetryMode.X_Symmetry;
+ else
+ return ColliderSymmetryMode.Z_Symmetry;
+ }
+ else
+ {
+ // (Z)
+ if (sameParent)
+ return ColliderSymmetryMode.Z_Symmetry;
+ if (Vector3.Dot(H, z) * Vector3.Dot(H, sz) > 0.0f)
+ {
+ if (xsign == false && ysign == false)
+ return ColliderSymmetryMode.XYZ_Symmetry;
+ else
+ return ColliderSymmetryMode.Z_Symmetry;
+ }
+ else if (xsign)
+ return ColliderSymmetryMode.Y_Symmetry;
+ else
+ return ColliderSymmetryMode.X_Symmetry;
+ }
+ }
+
+ bool GetHumanoidSymmetryBone(ref Transform target, Transform parent, Animator ani, HumanBodyBones src, HumanBodyBones dst)
+ {
+ var bone = ani.GetBoneTransform(src);
+ if (bone && parent == bone)
+ {
+ var bone2 = ani.GetBoneTransform(dst);
+ if (bone2)
+ {
+ target = bone2;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ ///
+ /// at/btの共通の親を返す。無い場合はnull。
+ ///
+ ///
+ ///
+ ///
+ Transform FindCommonParent(Transform at, Transform bt)
+ {
+ if (at == null || bt == null)
+ return null;
+
+ // ハッシュセットでatの親を格納
+ var atParents = new HashSet(16);
+ Transform current = at;
+ while (current != null)
+ {
+ atParents.Add(current);
+ current = current.parent;
+ }
+
+ // btの親をチェック
+ current = bt;
+ while (current != null)
+ {
+ if (atParents.Contains(current))
+ return current;
+ current = current.parent;
+ }
+
+ return null;
+ }
+
+ ///
+ /// 現在のシンメトリー設定に基づいて、シンメトリーのモードと対象を決定する
+ ///
+ internal void SetActiveSymmetryMode(bool firstOnly)
+ {
+ if (ActiveSymmetryMode.HasValue == false || firstOnly == false)
+ {
+ ActiveSymmetryMode = CalcSymmetryMode(out var target);
+ ActiveSymmetryTarget = target;
+ }
+ }
+
+ public int UseTeamCount => teamIdSet.Count;
+
+ //=========================================================================================
+ public void GetUsedTransform(HashSet transformSet)
+ {
+ if (symmetryTarget)
+ transformSet.Add(symmetryTarget);
+ }
+
+ public void ReplaceTransform(Dictionary replaceDict)
+ {
+ if (symmetryTarget)
+ {
+ int id = symmetryTarget.GetInstanceID();
+ if (id != 0 && replaceDict.ContainsKey(id))
+ symmetryTarget = replaceDict[id];
}
}
//=========================================================================================
protected virtual void Start()
{
+ SetActiveSymmetryMode(firstOnly: true);
}
protected virtual void OnValidate()
@@ -131,18 +413,22 @@ namespace MagicaCloth2
// コライダーを無効にする
foreach (int teamId in teamIdSet)
{
- MagicaManager.Collider.EnableCollider(this, teamId, false);
+ MagicaManager.Collider?.EnableCollider(this, teamId, false);
}
}
protected virtual void OnDestroy()
{
// コライダーを削除する
- foreach (int teamId in teamIdSet)
+ if (teamIdSet.Count > 0)
{
- MagicaManager.Collider.RemoveCollider(this, teamId);
+ var teamList = teamIdSet.ToList();
+ foreach (int teamId in teamList)
+ {
+ MagicaManager.Collider?.RemoveCollider(this, teamId);
+ }
+ teamIdSet.Clear();
}
- teamIdSet.Clear();
}
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs.meta
index 63bdbc33..a2407ce5 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderComponent.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs
new file mode 100644
index 00000000..7be93a13
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs
@@ -0,0 +1,52 @@
+// Magica Cloth 2.
+// Copyright (c) 2025 MagicaSoft.
+// https://magicasoft.jp
+namespace MagicaCloth2
+{
+ ///
+ /// シンメトリーモード
+ /// Symmetry mode.
+ ///
+ public enum ColliderSymmetryMode
+ {
+ None = 0,
+
+ ///
+ /// 人体の骨格を参照しすべて自動設定する
+ /// キャラクターにAnimatorコンポーネントが必要です
+ /// Automatically set everything based on the human skeleton.
+ /// Character must have an Animator component.
+ ///
+ AutomaticHumanBody = 1,
+
+ ///
+ /// SymmetryTargetの姿勢から自動設定します
+ /// Automatically set based on the SymmetryTarget's posture.
+ ///
+ AutomaticTarget = 2,
+
+ ///
+ /// X軸を左右対称
+ /// Symmetry on the X axis.
+ ///
+ X_Symmetry = 100,
+
+ ///
+ /// Y軸を左右対称
+ /// Symmetry on the Y axis.
+ ///
+ Y_Symmetry = 101,
+
+ ///
+ /// Z軸を左右対称
+ /// Symmetry on the Z axis.
+ ///
+ Z_Symmetry = 102,
+
+ ///
+ /// XYZ軸を左右対称
+ /// Symmetry on the XYZ axis.
+ ///
+ XYZ_Symmetry = 200,
+ }
+}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs.meta
new file mode 100644
index 00000000..39ece314
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs.meta
@@ -0,0 +1,18 @@
+fileFormatVersion: 2
+guid: 02f9b444838ae8a41916aab95109474e
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/ColliderSymmetryMode.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs
index 6a74354a..c832b499 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs
@@ -29,6 +29,12 @@ namespace MagicaCloth2
///
public Direction direction = Direction.X;
+ ///
+ /// Reverse direction.
+ /// 方向を逆転させる
+ ///
+ public bool reverseDirection = false;
+
///
/// 半径をStart/End別々に設定
/// Set radius separately for Start/End.
@@ -86,12 +92,14 @@ namespace MagicaCloth2
///
public Vector3 GetLocalDir()
{
+ float rev = reverseDirection ? -1 : 1;
+
if (direction == Direction.X)
- return Vector3.right;
+ return Vector3.right * rev;
else if (direction == Direction.Y)
- return Vector3.up;
+ return Vector3.up * rev;
else
- return Vector3.forward;
+ return Vector3.forward * rev;
}
///
@@ -108,6 +116,12 @@ namespace MagicaCloth2
return Vector3.up;
}
+ ///
+ /// 方向の逆転(基本的にカプセルコライダー用)
+ ///
+ ///
+ public override bool IsReverseDirection() => reverseDirection;
+
public override void DataValidate()
{
size.x = Mathf.Max(size.x, 0.001f);
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs.meta
index 77a804ba..0eaabaec 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaCapsuleCollider.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs.meta
index 099ff095..f598ae0f 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaPlaneCollider.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs.meta
index 9f3472ec..1fd076b5 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Collider/MagicaSphereCollider.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs
index c72604f0..5dc67fb0 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs
@@ -3,9 +3,7 @@
// https://magicasoft.jp
using System;
using System.Text;
-using Unity.Burst;
using Unity.Collections;
-using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
@@ -188,14 +186,6 @@ namespace MagicaCloth2
}
}
- //=========================================================================================
- NativeArray lengthBuffer;
- NativeArray localPosBuffer;
- NativeArray localRotBuffer;
- NativeArray rotationBuffer;
- NativeArray restorationVectorBuffer;
-
-
//=========================================================================================
public AngleConstraint()
{
@@ -203,174 +193,77 @@ namespace MagicaCloth2
public void Dispose()
{
- lengthBuffer.DisposeSafe();
- localPosBuffer.DisposeSafe();
- localRotBuffer.DisposeSafe();
- rotationBuffer.DisposeSafe();
- restorationVectorBuffer.DisposeSafe();
- }
-
- internal void WorkBufferUpdate()
- {
- int pcnt = MagicaManager.Simulation.ParticleCount;
- lengthBuffer.Resize(pcnt, options: NativeArrayOptions.UninitializedMemory);
- localPosBuffer.Resize(pcnt, options: NativeArrayOptions.UninitializedMemory);
- localRotBuffer.Resize(pcnt, options: NativeArrayOptions.UninitializedMemory);
- rotationBuffer.Resize(pcnt, options: NativeArrayOptions.UninitializedMemory);
- restorationVectorBuffer.Resize(pcnt, options: NativeArrayOptions.UninitializedMemory);
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"[AngleConstraint]");
- sb.AppendLine($" -lengthBuffer:{(lengthBuffer.IsCreated ? lengthBuffer.Length : 0)}");
- sb.AppendLine($" -localPosBuffer:{(localPosBuffer.IsCreated ? localPosBuffer.Length : 0)}");
- sb.AppendLine($" -localRotBuffer:{(localRotBuffer.IsCreated ? localRotBuffer.Length : 0)}");
- sb.AppendLine($" -rotationBuffer:{(rotationBuffer.IsCreated ? rotationBuffer.Length : 0)}");
- sb.AppendLine($" -restorationVectorBuffer:{(restorationVectorBuffer.IsCreated ? restorationVectorBuffer.Length : 0)}");
-
return sb.ToString();
}
//=========================================================================================
- ///
- /// 制約の解決
- ///
- ///
- ///
- ///
- internal unsafe JobHandle SolverConstraint(JobHandle jobHandle)
- {
- var tm = MagicaManager.Team;
- var sm = MagicaManager.Simulation;
- var vm = MagicaManager.VMesh;
-
- // 角度復元と角度制限を1つに統合したもの
- // 復元/制限ともにほぼMC1の移植。
- // 他のアルゴリズムを散々テストした結果、MC1の動きが一番映えるという結論に至る。
- // 微調整および堅牢性を上げるために反復回数を増やしている。
- var job = new AngleConstraintJob()
- {
- simulationPower = MagicaManager.Time.SimulationPower,
-
- stepBaseLineIndexArray = sm.processingStepBaseLine.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- vertexDepths = vm.vertexDepths.GetNativeArray(),
- vertexParentIndices = vm.vertexParentIndices.GetNativeArray(),
- baseLineStartDataIndices = vm.baseLineStartDataIndices.GetNativeArray(),
- baseLineDataCounts = vm.baseLineDataCounts.GetNativeArray(),
- baseLineData = vm.baseLineData.GetNativeArray(),
-
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- velocityPosArray = sm.velocityPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
-
- stepBasicPositionBuffer = sm.stepBasicPositionBuffer,
- stepBasicRotationBuffer = sm.stepBasicRotationBuffer,
-
- lengthBufferArray = lengthBuffer,
- localPosBufferArray = localPosBuffer,
- localRotBufferArray = localRotBuffer,
- rotationBufferArray = rotationBuffer,
- restorationVectorBufferArray = restorationVectorBuffer,
- };
- jobHandle = job.Schedule(sm.processingStepBaseLine.GetJobSchedulePtr(), 2, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct AngleConstraintJob : IJobParallelForDefer
- {
- public float4 simulationPower;
-
- [Unity.Collections.ReadOnly]
- public NativeArray stepBaseLineIndexArray;
-
+ // Solver
+ //=========================================================================================
+ internal static void SolverConstraint(
+ DataChunk chunk,
+ in float4 simulationPower,
// team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
-
+ ref TeamManager.TeamData tdata,
+ ref ClothParameters param,
// vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexDepths;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexParentIndices;
- [Unity.Collections.ReadOnly]
- public NativeArray baseLineStartDataIndices;
- [Unity.Collections.ReadOnly]
- public NativeArray baseLineDataCounts;
- [Unity.Collections.ReadOnly]
- public NativeArray baseLineData;
-
+ ref NativeArray attributes,
+ ref NativeArray vertexDepths,
+ ref NativeArray vertexParentIndices,
+ ref NativeArray baseLineStartDataIndices,
+ ref NativeArray baseLineDataCounts,
+ ref NativeArray baseLineData,
// particle
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
- [NativeDisableParallelForRestriction]
- public NativeArray velocityPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray frictionArray;
+ ref NativeArray nextPosArray,
+ ref NativeArray velocityPosArray,
+ ref NativeArray frictionArray,
+ // buffer
+ ref NativeArray stepBasicPositionBuffer,
+ ref NativeArray stepBasicRotationBuffer,
+ // buffer2
+ ref NativeArray lengthBufferArray,
+ ref NativeArray localPosBufferArray,
+ ref NativeArray localRotBufferArray,
+ ref NativeArray rotationBufferArray,
+ ref NativeArray restorationVectorBufferArray
+ )
+ {
+ var angleParam = param.angleConstraint;
+ if (angleParam.useAngleLimit == false && angleParam.useAngleRestoration == false)
+ return;
- // temp
- [Unity.Collections.ReadOnly]
- public NativeArray stepBasicPositionBuffer;
- [Unity.Collections.ReadOnly]
- public NativeArray stepBasicRotationBuffer;
- [NativeDisableParallelForRestriction]
- public NativeArray lengthBufferArray;
- [NativeDisableParallelForRestriction]
- public NativeArray localPosBufferArray;
- [NativeDisableParallelForRestriction]
- public NativeArray localRotBufferArray;
- [NativeDisableParallelForRestriction]
- public NativeArray rotationBufferArray;
- [NativeDisableParallelForRestriction]
- public NativeArray restorationVectorBufferArray;
+ int d_start = tdata.baseLineDataChunk.startIndex;
+ int p_start = tdata.particleChunk.startIndex;
+ int v_start = tdata.proxyCommonChunk.startIndex;
+
+ bool useAngleLimit = angleParam.useAngleLimit;
+ bool useAngleRestoration = angleParam.useAngleRestoration;
+
+ // 剛性
+ float limitStiffness = angleParam.limitstiffness;
+ float restorationAttn = angleParam.restorationVelocityAttenuation;
+
+ // 復元の重力減衰
+ // !この減衰は重力0でも発生するので注意!
+ float gravityFalloff = math.lerp(1.0f - angleParam.restorationGravityFalloff, 1.0f, tdata.gravityDot);
+ //Debug.Log($"gravityFalloff:{gravityFalloff}");
+ //float gravity = param.gravity;
+ //float3 gravityVector = gravity > Define.System.Epsilon ? param.gravityDirection : 0;
// ベースラインごと
- public void Execute(int index)
+ //int bindex = tdata.baseLineChunk.startIndex;
+ int bindex = tdata.baseLineChunk.startIndex + chunk.startIndex;
+ //for (int a = 0; a < tdata.baseLineChunk.dataLength; a++, bindex++)
+ for (int a = 0; a < chunk.dataLength; a++, bindex++)
{
- uint pack = (uint)stepBaseLineIndexArray[index];
- int teamId = DataUtility.Unpack32Hi(pack);
- int bindex = DataUtility.Unpack32Low(pack);
-
- // チームは有効であることが保証されている
- var tdata = teamDataArray[teamId];
- var param = parameterArray[teamId];
- var angleParam = param.angleConstraint;
- if (angleParam.useAngleLimit == false && angleParam.useAngleRestoration == false)
- return;
-
- int d_start = tdata.baseLineDataChunk.startIndex;
- int p_start = tdata.particleChunk.startIndex;
- int v_start = tdata.proxyCommonChunk.startIndex;
-
int start = baseLineStartDataIndices[bindex];
int dcnt = baseLineDataCounts[bindex];
- bool useAngleLimit = angleParam.useAngleLimit;
- bool useAngleRestoration = angleParam.useAngleRestoration;
-
- // 剛性
- float limitStiffness = angleParam.limitstiffness;
- float restorationAttn = angleParam.restorationVelocityAttenuation;
-
- // 復元の重力減衰
- // !この減衰は重力0でも発生するので注意!
- float gravityFalloff = math.lerp(1.0f - angleParam.restorationGravityFalloff, 1.0f, tdata.gravityDot);
- //Debug.Log($"gravityFalloff:{gravityFalloff}");
- //float gravity = param.gravity;
- //float3 gravityVector = gravity > Define.System.Epsilon ? param.gravityDirection : 0;
-
// バッファリング
int dataIndex = start + d_start;
for (int i = 0; i < dcnt; i++, dataIndex++)
@@ -402,15 +295,29 @@ namespace MagicaCloth2
// 親からの基本姿勢
var bv = bpos - pbpos;
- Develop.Assert(math.length(bv) > 0.0f);
- var v = math.normalize(bv);
- var ipq = math.inverse(pbrot);
- float3 localPos = math.mul(ipq, v);
- quaternion localRot = math.mul(ipq, brot);
+ float bvlen = math.length(bv);
+ if (vlen < Define.System.Epsilon || bvlen < Define.System.Epsilon)
+ {
+ // length=0
+ //Debug.Log($"NG1");
+ //エッジ長0対処
+ lengthBufferArray[pindex] = 0;
+ localPosBufferArray[pindex] = 0;
+ localRotBufferArray[pindex] = quaternion.identity;
+ }
+ else
+ {
+ //Develop.Assert(math.length(bv) > 0.0f);
+ //var v = math.normalize(bv);
+ var v = bv / bvlen;
+ var ipq = math.inverse(pbrot);
+ float3 localPos = math.mul(ipq, v);
+ quaternion localRot = math.mul(ipq, brot);
- lengthBufferArray[pindex] = vlen;
- localPosBufferArray[pindex] = localPos;
- localRotBufferArray[pindex] = localRot;
+ lengthBufferArray[pindex] = vlen;
+ localPosBufferArray[pindex] = localPos;
+ localRotBufferArray[pindex] = localRot;
+ }
}
if (useAngleRestoration)
@@ -418,6 +325,7 @@ namespace MagicaCloth2
// 復元ベクトル
float3 rv = bpos - pbpos;
restorationVectorBufferArray[pindex] = rv;
+ //Debug.Log($"[{pindex}] rv:{rv}");
}
}
}
@@ -478,19 +386,46 @@ namespace MagicaCloth2
// 現在のベクトル
float3 v = cpos - ppos;
+ float vlen = math.length(v);
+ if (vlen < Define.System.Epsilon)
+ {
+ //エッジ長0対処
+ //Debug.Log($"NG2");
+ goto EndAngleLimit;
+ }
// 復元すべきベクトル
float3 tv = math.mul(prot, localPos);
+ float tvlen = math.length(tv);
+ if (tvlen < Define.System.Epsilon)
+ {
+ //エッジ長0対処
+ //Debug.Log($"NG3");
+ float3 add = ppos - cpos;
+ nextPosArray[pindex] = ppos;
+ velocityPosArray[pindex] = velocityPosArray[pindex] + add;
+ rotationBufferArray[pindex] = math.mul(prot, localRot);
+ goto EndAngleLimit;
+ }
+
+ v /= vlen;
+ tv /= tvlen;
// ベクトル長修正
- float vlen = math.length(v);
float blen = lengthBufferArray[pindex];
vlen = math.lerp(vlen, blen, 0.5f); // 計算前の距離に徐々に近づける
- Develop.Assert(vlen > 0.0f);
- v = math.normalize(v) * vlen;
+ if (blen < Define.System.Epsilon || vlen < Define.System.Epsilon)
+ {
+ //エッジ長0対処
+ //Debug.Log($"NG4");
+ goto EndAngleLimit;
+ }
+ //Develop.Assert(vlen > 0.0f);
+ //v = math.normalize(v) * vlen;
+ v = v * vlen;
// ベクトル角度クランプ
- float maxAngleDeg = angleParam.limitCurveData.EvaluateCurve(cdepth);
+ float maxAngleDeg = angleParam.limitCurveData.MC2EvaluateCurve(cdepth);
float maxAngleRad = math.radians(maxAngleDeg);
float angle = MathUtility.Angle(v, tv);
float3 rv = v;
@@ -537,12 +472,23 @@ namespace MagicaCloth2
// 回転補正
v = cpos - ppos;
+ vlen = math.length(v);
+ if (vlen < Define.System.Epsilon)
+ {
+ //エッジ長0対処
+ //Debug.Log($"NG5");
+ goto EndAngleLimit;
+ }
+ v /= vlen;
var nrot = math.mul(prot, localRot);
- var q = MathUtility.FromToRotation(tv, v);
+ //var q = MathUtility.FromToRotation(tv, v);
+ var q = MathUtility.FromToRotationWithoutNormalize(tv, v);
nrot = math.mul(q, nrot);
rotationBufferArray[pindex] = nrot;
}
+ EndAngleLimit:
+
//=====================================================
// Angle Restoration
//=====================================================
@@ -550,14 +496,31 @@ namespace MagicaCloth2
{
//Debug.Log($"pindex:{pindex}, p_pindex:{p_pindex}");
- // 現在のベクトル
- float3 v = cpos - ppos;
-
// 復元すべきベクトル
float3 tv = restorationVectorBufferArray[pindex];
+ float tvlen = math.length(tv);
+ if (tvlen < Define.System.Epsilon)
+ {
+ //エッジ長0対処
+ //Debug.Log($"NG6");
+ float3 add = ppos - cpos;
+ nextPosArray[pindex] = ppos;
+ velocityPosArray[pindex] = velocityPosArray[pindex] + add;
+ continue;
+ }
+
+ // 現在のベクトル
+ float3 v = cpos - ppos;
+ float vlen = math.length(v);
+ if (vlen < Define.System.Epsilon)
+ {
+ //エッジ長0対処
+ //Debug.Log($"NG7");
+ continue;
+ }
// 復元力
- float restorationStiffness = angleParam.restorationStiffness.EvaluateCurveClamp01(cdepth);
+ float restorationStiffness = angleParam.restorationStiffness.MC2EvaluateCurveClamp01(cdepth);
restorationStiffness = math.saturate(restorationStiffness * simulationPower.w);
//int _pindex = indexBuffer[i] + p_start;
@@ -567,7 +530,7 @@ namespace MagicaCloth2
restorationStiffness *= gravityFalloff;
// 球面線形補間
- var q = MathUtility.FromToRotation(v, tv, restorationStiffness);
+ var q = MathUtility.FromToRotationWithoutNormalize(v / vlen, tv / tvlen, restorationStiffness);
float3 rv = math.mul(q, v);
// 回転中心割合
@@ -607,6 +570,25 @@ namespace MagicaCloth2
}
}
}
+
+ // バッファクリア
+ bindex = tdata.baseLineChunk.startIndex + chunk.startIndex;
+ for (int a = 0; a < chunk.dataLength; a++, bindex++)
+ {
+ int start = baseLineStartDataIndices[bindex];
+ int dcnt = baseLineDataCounts[bindex];
+
+ int dataIndex = start + d_start;
+ for (int i = 0; i < dcnt; i++, dataIndex++)
+ {
+ int l_index = baseLineData[dataIndex];
+ int pindex = p_start + l_index;
+
+ lengthBufferArray[pindex] = 0;
+ localPosBufferArray[pindex] = 0;
+ restorationVectorBufferArray[pindex] = 0;
+ }
+ }
}
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs.meta
index 5fc4bb29..96fabe85 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/AngleConstraint.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs
index d0368824..8ed7e83d 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs
@@ -4,10 +4,8 @@
using System;
using System.Collections.Generic;
using System.Text;
-using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
-using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
@@ -113,6 +111,11 @@ namespace MagicaCloth2
public void GetUsedTransform(HashSet transformSet)
{
+ colliderList.ForEach(x =>
+ {
+ if (x)
+ x.GetUsedTransform(transformSet);
+ });
foreach (var t in collisionBones)
{
if (t)
@@ -122,6 +125,11 @@ namespace MagicaCloth2
public void ReplaceTransform(Dictionary replaceDict)
{
+ colliderList.ForEach(x =>
+ {
+ if (x)
+ x.ReplaceTransform(replaceDict);
+ });
for (int i = 0; i < collisionBones.Count; i++)
{
var t = collisionBones[i];
@@ -184,9 +192,6 @@ namespace MagicaCloth2
}
}
- NativeArray tempFrictionArray;
- NativeArray tempNormalArray;
-
//=========================================================================================
public ColliderCollisionConstraint()
{
@@ -195,211 +200,69 @@ namespace MagicaCloth2
public void Dispose()
{
- tempFrictionArray.DisposeSafe();
- tempNormalArray.DisposeSafe();
- }
-
- ///
- /// 作業バッファ更新
- ///
- internal void WorkBufferUpdate()
- {
- int cnt = MagicaManager.Team.edgeColliderCollisionCount;
- if (cnt == 0)
- return;
-
- int pcnt = MagicaManager.Simulation.ParticleCount;
- tempFrictionArray.Resize(pcnt);
- tempNormalArray.Resize(pcnt * 3);
- //if (tempFrictionArray.IsCreated == false || tempFrictionArray.Length < pcnt)
- //{
- // if (tempFrictionArray.IsCreated)
- // tempFrictionArray.Dispose();
- // tempFrictionArray = new NativeArray(pcnt, Allocator.Persistent);
- //}
- //if (tempNormalArray.IsCreated == false || tempNormalArray.Length < pcnt * 3)
- //{
- // if (tempNormalArray.IsCreated)
- // tempNormalArray.Dispose();
- // tempNormalArray = new NativeArray(pcnt * 3, Allocator.Persistent);
- //}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"[ColliderCollisionConstraint]");
- sb.AppendLine($" -tempFrictionArray:{(tempFrictionArray.IsCreated ? tempFrictionArray.Length : 0)}");
- sb.AppendLine($" -tempNormalArray:{(tempNormalArray.IsCreated ? tempNormalArray.Length : 0)}");
-
return sb.ToString();
}
//=========================================================================================
- ///
- /// 制約の解決
- ///
- ///
- ///
- ///
- unsafe internal JobHandle SolverConstraint(JobHandle jobHandle)
- {
- var tm = MagicaManager.Team;
- var sm = MagicaManager.Simulation;
- var vm = MagicaManager.VMesh;
- var cm = MagicaManager.Collider;
-
- // Point
- var job = new PointColliderCollisionConstraintJob()
- {
- stepParticleIndexArray = sm.processingStepParticle.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- vertexDepths = vm.vertexDepths.GetNativeArray(),
-
- teamIdArray = sm.teamIdArray.GetNativeArray(),
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
- collisionNormalArray = sm.collisionNormalArray.GetNativeArray(),
- velocityPosArray = sm.velocityPosArray.GetNativeArray(),
- basePosArray = sm.basePosArray.GetNativeArray(),
-
- colliderFlagArray = cm.flagArray.GetNativeArray(),
- colliderWorkDataArray = cm.workDataArray.GetNativeArray(),
- };
- jobHandle = job.Schedule(sm.processingStepParticle.GetJobSchedulePtr(), 32, jobHandle);
-
- // Edge
- if (tm.edgeColliderCollisionCount > 0)
- {
- var job2 = new EdgeColliderCollisionConstraintJob()
- {
- stepEdgeCollisionIndexArray = sm.processingStepEdgeCollision.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- vertexDepths = vm.vertexDepths.GetNativeArray(),
- edgeTeamIdArray = vm.edgeTeamIdArray.GetNativeArray(),
- edges = vm.edges.GetNativeArray(),
-
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
- collisionNormalArray = sm.collisionNormalArray.GetNativeArray(),
- velocityPosArray = sm.velocityPosArray.GetNativeArray(),
-
- colliderFlagArray = cm.flagArray.GetNativeArray(),
- colliderWorkDataArray = cm.workDataArray.GetNativeArray(),
-
- countArray = sm.countArray,
- sumArray = sm.sumArray,
- tempFrictionArray = tempFrictionArray,
- tempNormalArray = tempNormalArray,
- };
- jobHandle = job2.Schedule(sm.processingStepEdgeCollision.GetJobSchedulePtr(), 32, jobHandle);
-
- // 集計
- var job3 = new SolveEdgeBufferAndClearJob()
- {
- jobParticleIndexList = sm.processingStepParticle.Buffer,
-
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
- velocityPosArray = sm.velocityPosArray.GetNativeArray(),
- collisionNormalArray = sm.collisionNormalArray.GetNativeArray(),
-
- countArray = sm.countArray,
- sumArray = sm.sumArray,
- tempFrictionArray = tempFrictionArray,
- tempNormalArray = tempNormalArray,
- };
- jobHandle = job3.Schedule(sm.processingStepParticle.GetJobSchedulePtr(), 32, jobHandle);
- }
-
- return jobHandle;
- }
-
+ // Point Solver
//=========================================================================================
- ///
- /// Pointコライダー衝突判定
- ///
- [BurstCompile]
- struct PointColliderCollisionConstraintJob : IJobParallelForDefer
- {
- [Unity.Collections.ReadOnly]
- public NativeArray stepParticleIndexArray;
-
+ internal static void SolverPointConstraint(
+ DataChunk chunk,
// team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
-
+ ref TeamManager.TeamData tdata,
+ ref ClothParameters param,
// vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexDepths;
-
+ ref NativeArray attributes,
+ ref NativeArray vertexDepths,
// particle
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
- [NativeDisableParallelForRestriction]
- public NativeArray frictionArray;
- [NativeDisableParallelForRestriction]
- public NativeArray collisionNormalArray;
- [NativeDisableParallelForRestriction]
- public NativeArray velocityPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray basePosArray;
-
+ ref NativeArray nextPosArray,
+ ref NativeArray frictionArray,
+ ref NativeArray collisionNormalArray,
+ ref NativeArray velocityPosArray,
+ ref NativeArray basePosArray,
// collider
- [Unity.Collections.ReadOnly]
- public NativeArray colliderFlagArray;
- [Unity.Collections.ReadOnly]
- public NativeArray colliderWorkDataArray;
+ ref NativeArray colliderFlagArray,
+ ref NativeArray colliderWorkDataArray
+ )
+ {
+ if (tdata.UseColliderCount == 0)
+ return;
+ if (param.colliderCollisionConstraint.mode != Mode.Point)
+ return;
+ if (chunk.IsValid == false)
+ return;
- // ステップ実行パーティクルごと
- public void Execute(int index)
+ bool isSpring = tdata.IsSpring;
+
+ // ■Point
+ // パーティクルごと
+ //int pindex = tdata.particleChunk.startIndex;
+ //int vindex = tdata.proxyCommonChunk.startIndex;
+ int pindex = tdata.particleChunk.startIndex + chunk.startIndex;
+ int vindex = tdata.proxyCommonChunk.startIndex + chunk.startIndex;
+ //for (int k = 0; k < tdata.particleChunk.dataLength; k++, pindex++, vindex++)
+ for (int k = 0; k < chunk.dataLength; k++, pindex++, vindex++)
{
- // このパーティクルは有効であることが保証されている
- int pindex = stepParticleIndexArray[index];
- int teamId = teamIdArray[pindex];
- var tdata = teamDataArray[teamId];
- if (tdata.colliderCount == 0)
- return;
-
- // パラメータ
- var param = parameterArray[teamId];
-
- // モード判定
- var mode = param.colliderCollisionConstraint.mode;
- if (mode != Mode.Point)
- return;
-
// パーティクル情報
var nextPos = nextPosArray[pindex];
- int l_index = pindex - tdata.particleChunk.startIndex;
- int vindex = tdata.proxyCommonChunk.startIndex + l_index;
var attr = attributes[vindex];
if (attr.IsInvalid() || attr.IsDisableCollision())
- return;
+ continue;
if (attr.IsMove() == false && tdata.IsSpring == false) // スプリング利用時は固定頂点も通す
- return;
+ continue;
float depth = vertexDepths[vindex];
// BoneSpringでは自動的にソフトコライダーとなる
- bool isSpring = tdata.IsSpring;
var basePos = isSpring ? basePosArray[pindex] : float3.zero; // ソフトコライダーのみbasePosが必要
// パーティクル半径
- float radius = math.max(param.radiusCurveData.EvaluateCurve(depth), 0.0001f); // safe;
+ float radius = math.max(param.radiusCurveData.MC2EvaluateCurve(depth), 0.0001f); // safe;
// チームスケール倍率
radius *= tdata.scaleRatio;
@@ -426,7 +289,7 @@ namespace MagicaCloth2
aabb.Expand(cfr);
// BoneSpringでの最大押し出し距離
- float maxLength = isSpring ? math.max(param.colliderCollisionConstraint.limitDistance.EvaluateCurve(depth), 0.0001f) * tdata.scaleRatio : -1; // チームスケール倍率
+ float maxLength = isSpring ? math.max(param.colliderCollisionConstraint.limitDistance.MC2EvaluateCurve(depth), 0.0001f) * tdata.scaleRatio : -1; // チームスケール倍率
// チーム内のコライダーをループ
int cindex = tdata.colliderChunk.startIndex;
@@ -447,7 +310,6 @@ namespace MagicaCloth2
{
case ColliderManager.ColliderType.Sphere:
// ソフトコライダーはSphereのみ
- //dist = PointSphereColliderDetection(ref _nextPos, basePos, radius, aabb, cwork, maxLength, out n);
dist = PointSphereColliderDetection(ref _nextPos, basePos, radius, aabb, cwork, isSpring, maxLength, out n);
break;
case ColliderManager.ColliderType.CapsuleX_Center:
@@ -473,6 +335,7 @@ namespace MagicaCloth2
addPos += (_nextPos - nextPos);
addN += n;
addCnt++;
+ //Debug.Log($"Collision!");
}
// コライダーに一定距離近づいている場合(動摩擦/静止摩擦が影響する)
@@ -531,242 +394,209 @@ namespace MagicaCloth2
velocityPosArray[pindex] = velocityPosArray[pindex] + addPos;
}
}
+ }
- ///
- /// Point球衝突判定
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- float PointSphereColliderDetection(ref float3 nextpos, in float3 basePos, float radius, in AABB aabb, in ColliderManager.WorkData cwork, bool isSpring, float maxLength, out float3 normal)
- {
- // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
- normal = 0;
+ static float PointSphereColliderDetection(
+ ref float3 nextpos,
+ in float3 basePos,
+ float radius,
+ in AABB aabb,
+ in ColliderManager.WorkData cwork,
+ bool isSpring,
+ float maxLength,
+ out float3 normal
+ )
+ {
+ // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
+ normal = 0;
- //=========================================================
- // AABB判定
- //=========================================================
- if (aabb.Overlaps(cwork.aabb) == false)
- return float.MaxValue;
+ //=========================================================
+ // AABB判定
+ //=========================================================
+ if (aabb.Overlaps(cwork.aabb) == false)
+ return float.MaxValue;
- var oldpos = nextpos;
+ var oldpos = nextpos;
- //=========================================================
- // 衝突解決
- //=========================================================
- float3 coldpos = cwork.oldPos.c0;
- float3 cpos = cwork.nextPos.c0;
- float cradius = cwork.radius.x;
+ //=========================================================
+ // 衝突解決
+ //=========================================================
+ float3 coldpos = cwork.oldPos.c0;
+ float3 cpos = cwork.nextPos.c0;
+ float cradius = cwork.radius.x;
- // 移動前のコライダーに対するローカル位置から移動後コライダーの押し出し平面を求める
- float3 c, n, v;
- v = nextpos - coldpos;
- Develop.Assert(math.length(v) > 0.0f);
- n = math.normalize(v);
- c = cpos + n * (cradius + radius);
+ // 移動前のコライダーに対するローカル位置から移動後コライダーの押し出し平面を求める
+ float3 c, n, v;
+ v = nextpos - coldpos;
+ Develop.Assert(math.length(v) > 0.0f);
+ n = math.normalize(v);
+ c = cpos + n * (cradius + radius);
- // 衝突法線
- normal = n;
+ // 衝突法線
+ normal = n;
- // c = 平面位置
- // n = 平面方向
- // 平面衝突判定と押し出し
- //return MathUtility.IntersectPointPlaneDist(c, n, nextpos, out nextpos);
- float dist = MathUtility.IntersectPointPlaneDist(c, n, nextpos, out nextpos);
+ // c = 平面位置
+ // n = 平面方向
+ // 平面衝突判定と押し出し
+ //return MathUtility.IntersectPointPlaneDist(c, n, nextpos, out nextpos);
+ float dist = MathUtility.IntersectPointPlaneDist(c, n, nextpos, out nextpos);
#if true
- // BoneSpring
- if (maxLength > 0.0f)
- {
- // (1)距離制限
- nextpos = MathUtility.ClampDistance(basePos, nextpos, maxLength);
+ // BoneSpring
+ if (maxLength > 0.0f)
+ {
+ // (1)距離制限
+ nextpos = MathUtility.ClampDistance(basePos, nextpos, maxLength);
- // (2)反発力減衰
- float l = math.distance(basePos, nextpos);
- float t = math.saturate(l / radius); // 半径基準
- //float t = math.saturate(l / maxLength);
- t = math.lerp(0.0f, 0.85f, t); // 最低でも少し反発を残す
- nextpos = math.lerp(nextpos, oldpos, t);
+ // (2)反発力減衰
+ float l = math.distance(basePos, nextpos);
+ float t = math.saturate(l / radius); // 半径基準
+ //float t = math.saturate(l / maxLength);
+ t = math.lerp(0.0f, 0.85f, t); // 最低でも少し反発を残す
+ nextpos = math.lerp(nextpos, oldpos, t);
- // 衝突平面までの距離は摩擦影響を抑えるためスケールする
- dist *= 3.0f;
- }
+ // 衝突平面までの距離は摩擦影響を抑えるためスケールする
+ dist *= 3.0f;
+ }
#endif
- return dist;
- }
+ return dist;
+ }
- ///
- /// Point平面衝突判定(無限平面)
- ///
- ///
- ///
- ///
- ///
- ///
- float PointPlaneColliderDetction(ref float3 nextpos, float radius, in ColliderManager.WorkData cwork, out float3 normal)
- {
- // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
+ static float PointPlaneColliderDetction(
+ ref float3 nextpos,
+ float radius,
+ in ColliderManager.WorkData cwork,
+ out float3 normal
+ )
+ {
+ // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
- // コライダー情報
- var cpos = cwork.nextPos.c0;
- var n = cwork.oldPos.c0; // ここに押し出し法線
+ // コライダー情報
+ var cpos = cwork.nextPos.c0;
+ var n = cwork.oldPos.c0; // ここに押し出し法線
- // 衝突法線
- normal = n;
+ // 衝突法線
+ normal = n;
- // c = 平面位置(パーティクル半径分オフセット)
- // n = 平面方向
- // 平面衝突判定と押し出し
- // 平面との距離を返す(押し出しの場合は0.0)
- return MathUtility.IntersectPointPlaneDist(cpos + n * radius, n, nextpos, out nextpos);
- }
+ // c = 平面位置(パーティクル半径分オフセット)
+ // n = 平面方向
+ // 平面衝突判定と押し出し
+ // 平面との距離を返す(押し出しの場合は0.0)
+ return MathUtility.IntersectPointPlaneDist(cpos + n * radius, n, nextpos, out nextpos);
+ }
- ///
- /// Pointカプセル衝突判定
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- float PointCapsuleColliderDetection(ref float3 nextpos, float radius, in AABB aabb, in ColliderManager.WorkData cwork, out float3 normal)
- {
- // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
- normal = 0;
+ static float PointCapsuleColliderDetection(
+ ref float3 nextpos,
+ float radius,
+ in AABB aabb,
+ in ColliderManager.WorkData cwork,
+ out float3 normal
+ )
+ {
+ // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
+ normal = 0;
- //=========================================================
- // AABB判定
- //=========================================================
- if (aabb.Overlaps(cwork.aabb) == false)
- return float.MaxValue;
+ //=========================================================
+ // AABB判定
+ //=========================================================
+ if (aabb.Overlaps(cwork.aabb) == false)
+ return float.MaxValue;
- // コライダー情報
- float3 soldpos = cwork.oldPos.c0;
- float3 eoldpos = cwork.oldPos.c1;
- float3 spos = cwork.nextPos.c0;
- float3 epos = cwork.nextPos.c1;
- float sr = cwork.radius.x;
- float er = cwork.radius.y;
+ // コライダー情報
+ float3 soldpos = cwork.oldPos.c0;
+ float3 eoldpos = cwork.oldPos.c1;
+ float3 spos = cwork.nextPos.c0;
+ float3 epos = cwork.nextPos.c1;
+ float sr = cwork.radius.x;
+ float er = cwork.radius.y;
- //=========================================================
- // 衝突解決
- //=========================================================
- // 移動前のコライダー位置から押し出し平面を割り出す
- float t = MathUtility.ClosestPtPointSegmentRatio(nextpos, soldpos, eoldpos);
- float r = math.lerp(sr, er, t);
- float3 d = math.lerp(soldpos, eoldpos, t);
- float3 v = nextpos - d;
+ //=========================================================
+ // 衝突解決
+ //=========================================================
+ // 移動前のコライダー位置から押し出し平面を割り出す
+ float t = MathUtility.ClosestPtPointSegmentRatio(nextpos, soldpos, eoldpos);
+ float r = math.lerp(sr, er, t);
+ float3 d = math.lerp(soldpos, eoldpos, t);
+ float3 v = nextpos - d;
- // 移動前コライダーのローカルベクトル
- float3 lv = math.mul(cwork.inverseOldRot, v);
+ // 移動前コライダーのローカルベクトル
+ float3 lv = math.mul(cwork.inverseOldRot, v);
- // 移動後コライダーに変換
- d = math.lerp(spos, epos, t);
- v = math.mul(cwork.rot, lv);
- Develop.Assert(math.length(v) > 0.0f);
- float3 n = math.normalize(v);
- float3 c = d + n * (r + radius);
+ // 移動後コライダーに変換
+ d = math.lerp(spos, epos, t);
+ v = math.mul(cwork.rot, lv);
+ Develop.Assert(math.length(v) > 0.0f);
+ float3 n = math.normalize(v);
+ float3 c = d + n * (r + radius);
- // 衝突法線
- normal = n;
+ // 衝突法線
+ normal = n;
- // c = 平面位置
- // n = 平面方向
- // 平面衝突判定と押し出し
- return MathUtility.IntersectPointPlaneDist(c, n, nextpos, out nextpos);
- }
+ // c = 平面位置
+ // n = 平面方向
+ // 平面衝突判定と押し出し
+ return MathUtility.IntersectPointPlaneDist(c, n, nextpos, out nextpos);
}
//=========================================================================================
- ///
- /// Edgeコライダー衝突判定
- ///
- [BurstCompile]
- unsafe struct EdgeColliderCollisionConstraintJob : IJobParallelForDefer
- {
- [Unity.Collections.ReadOnly]
- public NativeArray stepEdgeCollisionIndexArray;
-
+ // Edge Solver
+ //=========================================================================================
+ internal unsafe static void SolverEdgeConstraint(
+ DataChunk chunk,
// team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
-
+ ref TeamManager.TeamData tdata,
+ ref ClothParameters param,
// vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexDepths;
- [Unity.Collections.ReadOnly]
- public NativeArray edgeTeamIdArray;
- [Unity.Collections.ReadOnly]
- public NativeArray edges;
-
+ ref NativeArray attributes,
+ ref NativeArray vertexDepths,
+ ref NativeArray edges,
// particle
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
- [NativeDisableParallelForRestriction]
- public NativeArray frictionArray;
- [NativeDisableParallelForRestriction]
- public NativeArray collisionNormalArray;
- [NativeDisableParallelForRestriction]
- public NativeArray velocityPosArray;
-
+ ref NativeArray nextPosArray,
// collider
- [Unity.Collections.ReadOnly]
- public NativeArray colliderFlagArray;
- [Unity.Collections.ReadOnly]
- public NativeArray colliderWorkDataArray;
+ ref NativeArray colliderFlagArray,
+ ref NativeArray colliderWorkDataArray,
+ // buffer2
+ ref NativeArray tempVectorBufferA,
+ ref NativeArray tempVectorBufferB,
+ ref NativeArray tempCountBuffer,
+ ref NativeArray tempFloatBufferA
+ )
+ {
+ if (tdata.UseColliderCount == 0)
+ return;
+ if (param.colliderCollisionConstraint.mode != Mode.Edge)
+ return;
+ if (chunk.IsValid == false)
+ return;
- // output
- [NativeDisableParallelForRestriction]
- public NativeArray countArray;
- [NativeDisableParallelForRestriction]
- public NativeArray sumArray;
- [NativeDisableParallelForRestriction]
- public NativeArray tempFrictionArray;
- [NativeDisableParallelForRestriction]
- public NativeArray tempNormalArray;
+ // ■Edge
+ int* vecAPt = (int*)tempVectorBufferA.GetUnsafePtr();
+ int* vecBPt = (int*)tempVectorBufferB.GetUnsafePtr();
+ int* cntPt = (int*)tempCountBuffer.GetUnsafePtr();
+ int* floatPt = (int*)tempFloatBufferA.GetUnsafePtr();
- // ステップ実行エッジごと
- public void Execute(int index)
+ // ■計算
+ // エッジごと
+ int vstart = tdata.proxyCommonChunk.startIndex;
+ //int eindex = tdata.proxyEdgeChunk.startIndex;
+ int eindex = tdata.proxyEdgeChunk.startIndex + chunk.startIndex;
+ //for (int k = 0; k < tdata.proxyEdgeChunk.dataLength; k++, eindex++)
+ for (int k = 0; k < chunk.dataLength; k++, eindex++)
{
- // このエッジは有効であることが保証されている
- int eindex = stepEdgeCollisionIndexArray[index];
- int teamId = edgeTeamIdArray[eindex];
- var tdata = teamDataArray[teamId];
- if (tdata.colliderCount == 0)
- return;
-
- // パラメータ
- var param = parameterArray[teamId];
-
- // モード判定
- var mode = param.colliderCollisionConstraint.mode;
- if (mode != Mode.Edge)
- return;
-
// エッジ情報
- int vstart = tdata.proxyCommonChunk.startIndex;
int2 edge = edges[eindex];
int2 vE = edge + vstart;
var attrE0 = attributes[vE.x];
var attrE1 = attributes[vE.y];
// 両方とも固定なら不要
if (attrE0.IsMove() == false && attrE1.IsMove() == false)
- return;
+ continue;
int pstart = tdata.particleChunk.startIndex;
int2 pE = edge + pstart;
float3x2 nextPosE = new float3x2(nextPosArray[pE.x], nextPosArray[pE.y]);
float2 depthE = new float2(vertexDepths[vE.x], vertexDepths[vE.y]);
- float2 radiusE = new float2(param.radiusCurveData.EvaluateCurve(depthE.x), param.radiusCurveData.EvaluateCurve(depthE.y));
+ float2 radiusE = new float2(param.radiusCurveData.MC2EvaluateCurve(depthE.x), param.radiusCurveData.MC2EvaluateCurve(depthE.y));
// チームスケール倍率
radiusE *= tdata.scaleRatio;
@@ -781,12 +611,6 @@ namespace MagicaCloth2
float3 collisionNormal = 0;
float3 n = 0;
- // 書き込みポインタ
- int* cntPt = (int*)countArray.GetUnsafePtr();
- int* sumPt = (int*)sumArray.GetUnsafePtr();
- int* frictionPt = (int*)tempFrictionArray.GetUnsafePtr();
- int* normalPt = (int*)tempNormalArray.GetUnsafePtr();
-
// エッジAABB
var aabbE = new AABB(nextPosE.c0 - radiusE.x, nextPosE.c0 + radiusE.x);
var aabbE1 = new AABB(nextPosE.c1 - radiusE.y, nextPosE.c1 + radiusE.y);
@@ -868,8 +692,8 @@ namespace MagicaCloth2
addPos *= t;
// 書き戻し
- InterlockUtility.AddFloat3(pE.x, addPos.c0, cntPt, sumPt);
- InterlockUtility.AddFloat3(pE.y, addPos.c1, cntPt, sumPt);
+ InterlockUtility.AddFloat3(pE.x, addPos.c0, cntPt, vecAPt);
+ InterlockUtility.AddFloat3(pE.y, addPos.c1, cntPt, vecAPt);
}
}
@@ -881,316 +705,356 @@ namespace MagicaCloth2
var friction = 1.0f - math.saturate(mindist / cfr);
// 大きい場合のみ上書き
- InterlockUtility.Max(pE.x, friction, frictionPt);
- InterlockUtility.Max(pE.y, friction, frictionPt);
+ InterlockUtility.Max(pE.x, friction, floatPt);
+ InterlockUtility.Max(pE.y, friction, floatPt);
// 摩擦用接触法線平均化
//Develop.Assert(math.length(collisionNormal) > 0.0f);
collisionNormal = math.normalize(collisionNormal);
// 接触法線集計(すべて加算する)
- InterlockUtility.AddFloat3(pE.x, collisionNormal, normalPt);
- InterlockUtility.AddFloat3(pE.y, collisionNormal, normalPt);
+ InterlockUtility.AddFloat3(pE.x, collisionNormal, vecBPt);
+ InterlockUtility.AddFloat3(pE.y, collisionNormal, vecBPt);
}
}
-
- float EdgeSphereColliderDetection(ref float3x2 nextPosE, in float2 radiusE, in AABB aabbE, float cfr, in ColliderManager.WorkData cwork, out float3 normal)
- {
- // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
- normal = 0;
-
- //=========================================================
- // AABB判定
- //=========================================================
- if (aabbE.Overlaps(cwork.aabb) == false)
- return float.MaxValue;
-
- // コライダー情報
- float3 coldpos = cwork.oldPos.c0;
- float3 cpos = cwork.nextPos.c0;
- float cradius = cwork.radius.x;
-
- //=========================================================
- // 衝突判定
- //=========================================================
- // 移動前球に対する線分の最近接点
- float s;
- s = MathUtility.ClosestPtPointSegmentRatio(coldpos, nextPosE.c0, nextPosE.c1);
- float3 c = math.lerp(nextPosE.c0, nextPosE.c1, s);
-
- // 最近接点の距離
- var v = c - coldpos;
- float clen = math.length(v);
- if (clen < 1e-09f)
- return float.MaxValue;
-
- // 押し出し法線
- float3 n = v / clen;
- normal = n;
-
- // 変位
- float3 db = cpos - coldpos;
-
- // 変位をnに投影して距離チェック
- float l1 = math.dot(n, db);
- float l = clen - l1;
-
- // 厚み
- float rA = math.lerp(radiusE.x, radiusE.y, s);
- float rB = cradius;
- float thickness = rA + rB;
-
- // 接触判定
- if (l > (thickness + cfr))
- return float.MaxValue;
-
- //=========================================================
- // 衝突解決
- //=========================================================
- // 接触法線に現在の距離を投影させる
- v = c - cpos;
- l = math.dot(n, v);
- if (l > thickness)
- {
- // 接触なし
- // 接触面までの距離を返す
- return l - thickness;
- }
-
- // 離す距離
- float C = thickness - l;
-
- // エッジのみを引き離す
- //float b0 = 1.0f - t;
- //float b1 = t;
- float2 b = new float2(1.0f - s, s);
-
- //float3 grad0 = n * b0;
- //float3 grad1 = n * b1;
- float3x2 grad = new float3x2(n * b.x, n * b.y);
-
- //float S = b0 * b0 + b1 * b1;
- float S = math.dot(b, b);
- if (S == 0.0f)
- return float.MaxValue;
-
- S = C / S;
-
- //float3 corr0 = S * grad0;
- //float3 corr1 = S * grad1;
- float3x2 corr = grad * S;
-
- //=========================================================
- // 反映
- //=========================================================
- nextPosE += corr;
-
- // 押し出し距離を返す
- return -C;
- }
-
- float EdgeCapsuleColliderDetection(ref float3x2 nextPosE, in float2 radiusE, in AABB aabbE, float cfr, in ColliderManager.WorkData cwork, out float3 normal)
- {
- // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
- normal = 0;
-
- //=========================================================
- // AABB判定
- //=========================================================
- if (aabbE.Overlaps(cwork.aabb) == false)
- return float.MaxValue;
-
- // コライダー情報
- float3 soldpos = cwork.oldPos.c0;
- float3 eoldpos = cwork.oldPos.c1;
- float3 spos = cwork.nextPos.c0;
- float3 epos = cwork.nextPos.c1;
- float sr = cwork.radius.x;
- float er = cwork.radius.y;
-
- //=========================================================
- // 衝突判定
- //=========================================================
- // 移動前の2つの線分の最近接点
- float s, t;
- float3 cA, cB;
- float csqlen = MathUtility.ClosestPtSegmentSegment(nextPosE.c0, nextPosE.c1, soldpos, eoldpos, out s, out t, out cA, out cB);
- float clen = math.sqrt(csqlen); // 最近接点の距離
- if (clen < 1e-09f)
- return float.MaxValue;
-
- // 押出法線
- var v = cA - cB;
- Develop.Assert(math.length(v) > 0.0f);
- float3 n = math.normalize(v);
- normal = n;
-
- // 変位
- float3 dB0 = spos - soldpos;
- float3 dB1 = epos - eoldpos;
-
-
- // 最近接点での変位
- float3 db = math.lerp(dB0, dB1, t);
-
- // 変位da,dbをnに投影して距離チェック
- float l1 = math.dot(n, db);
- float l = clen - l1;
-
- // 厚み
- float rA = math.lerp(radiusE.x, radiusE.y, s);
- float rB = math.lerp(sr, er, t);
- float thickness = rA + rB;
-
- // 接触判定
- if (l > (thickness + cfr))
- return float.MaxValue;
-
- //=========================================================
- // 衝突解決
- //=========================================================
- // 接触法線に現在の距離を投影させる
- var d = math.lerp(spos, epos, t);
- v = cA - d;
- l = math.dot(n, v);
- //Debug.Log($"l:{l}");
- if (l > thickness)
- {
- // 接触なし
- // 接触面までの距離を返す
- return l - thickness;
- }
-
- // 離す距離
- float C = thickness - l;
- //Debug.Log($"C:{C}");
-
- // エッジのみを引き離す
- //float b0 = 1.0f - s;
- //float b1 = s;
- float2 b = new float2(1.0f - s, s);
-
- //float3 grad0 = n * b0;
- //float3 grad1 = n * b1;
- float3x2 grad = new float3x2(n * b.x, n * b.y);
-
- //float S = invMass0 * b0 * b0 + invMass1 * b1 * b1;
- float S = math.dot(b, b);
- if (S == 0.0f)
- return float.MaxValue;
-
- S = C / S;
-
- //float3 corr0 = S * invMass0 * grad0;
- //float3 corr1 = S * invMass1 * grad1;
- float3x2 corr = grad * S;
-
- //=========================================================
- // 反映
- //=========================================================
- nextPosE += corr;
-
- // 押し出し距離を返す
- return -C;
- }
-
- float EdgePlaneColliderDetection(ref float3x2 nextPosE, in float2 radiusE, in ColliderManager.WorkData cwork, out float3 normal)
- {
- // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
-
- // コライダー情報
- var cpos = cwork.nextPos.c0;
- var n = cwork.oldPos.c0; // ここに押し出し法線
-
- // 衝突法線
- normal = n;
-
- // c = 平面位置
- // n = 平面方向
- // 平面衝突判定と押し出し
- // 平面との距離を返す(押し出しの場合は0.0)
- float dist0 = MathUtility.IntersectPointPlaneDist(cpos + n * radiusE.x, n, nextPosE.c0, out nextPosE.c0);
- float dist1 = MathUtility.IntersectPointPlaneDist(cpos + n * radiusE.y, n, nextPosE.c1, out nextPosE.c1);
-
- return math.min(dist0, dist1);
- }
}
- ///
- /// エッジコライダーコリジョン結果の集計
- ///
- [BurstCompile]
- struct SolveEdgeBufferAndClearJob : IJobParallelForDefer
- {
- [Unity.Collections.ReadOnly]
- public NativeArray jobParticleIndexList;
-
+ internal unsafe static void SumEdgeConstraint(
+ DataChunk chunk,
+ // team
+ ref TeamManager.TeamData tdata,
+ ref ClothParameters param,
// particle
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
- [NativeDisableParallelForRestriction]
- public NativeArray frictionArray;
- [NativeDisableParallelForRestriction]
- public NativeArray collisionNormalArray;
- [NativeDisableParallelForRestriction]
- public NativeArray velocityPosArray;
+ ref NativeArray nextPosArray,
+ ref NativeArray frictionArray,
+ ref NativeArray collisionNormalArray,
+ // buffer2
+ ref NativeArray tempVectorBufferA,
+ ref NativeArray tempVectorBufferB,
+ ref NativeArray tempCountBuffer,
+ ref NativeArray tempFloatBufferA
+ )
+ {
+ if (tdata.UseColliderCount == 0)
+ return;
+ if (param.colliderCollisionConstraint.mode != Mode.Edge)
+ return;
+ if (chunk.IsValid == false)
+ return;
- // aggregate
- [NativeDisableParallelForRestriction]
- public NativeArray countArray;
- [NativeDisableParallelForRestriction]
- public NativeArray sumArray;
- [NativeDisableParallelForRestriction]
- public NativeArray tempFrictionArray;
- [NativeDisableParallelForRestriction]
- public NativeArray tempNormalArray;
+ // ■Edge
+ int* vecAPt = (int*)tempVectorBufferA.GetUnsafePtr();
+ int* vecBPt = (int*)tempVectorBufferB.GetUnsafePtr();
+ int* cntPt = (int*)tempCountBuffer.GetUnsafePtr();
+ int* floatPt = (int*)tempFloatBufferA.GetUnsafePtr();
- // ステップ有効パーティクルごと
- public void Execute(int index)
+ // ■集計
+ // パーティクルごと
+ //int pindex = tdata.particleChunk.startIndex;
+ //int vindex = tdata.proxyCommonChunk.startIndex;
+ int pindex = tdata.particleChunk.startIndex + chunk.startIndex;
+ int vindex = tdata.proxyCommonChunk.startIndex + chunk.startIndex;
+ //for (int k = 0; k < tdata.particleChunk.dataLength; k++, pindex++, vindex++)
+ for (int k = 0; k < chunk.dataLength; k++, pindex++, vindex++)
{
- int pindex = jobParticleIndexList[index];
-
// nextpos
- int count = countArray[pindex];
- int dataIndex = pindex * 3;
+ int count = tempCountBuffer[pindex];
if (count > 0)
{
- float3 add = InterlockUtility.ReadAverageFloat3(pindex, countArray, sumArray);
+ float3 add = InterlockUtility.ReadAverageFloat3(pindex, cntPt, vecAPt);
// 書き出し
nextPosArray[pindex] = nextPosArray[pindex] + add;
-
- // 速度影響
- //float attn = param.colliderCollisionConstraint.colliderVelocityAttenuation;
- //float attn = Define.System.ColliderCollisionVelocityAttenuation;
- //velocityPosArray[pindex] = velocityPosArray[pindex] + add * attn;
-
- // バッファクリア
- countArray[pindex] = 0;
- sumArray[dataIndex] = 0;
- sumArray[dataIndex + 1] = 0;
- sumArray[dataIndex + 2] = 0;
}
// friction
- float f = InterlockUtility.ReadFloat(pindex, tempFrictionArray);
+ float f = InterlockUtility.ReadFloat(pindex, floatPt);
if (f > 0.0f && f > frictionArray[pindex])
{
frictionArray[pindex] = f;
- tempFrictionArray[pindex] = 0;
}
// collision normal
- float3 n = InterlockUtility.ReadFloat3(pindex, tempNormalArray);
+ float3 n = InterlockUtility.ReadFloat3(pindex, vecBPt);
if (math.lengthsq(n) > 0.0f)
{
n = math.normalize(n);
collisionNormalArray[pindex] = n;
- tempNormalArray[dataIndex] = 0;
- tempNormalArray[dataIndex + 1] = 0;
- tempNormalArray[dataIndex + 2] = 0;
}
+
+ // バッファクリア
+ tempVectorBufferA[pindex] = 0;
+ tempVectorBufferB[pindex] = 0;
+ tempCountBuffer[pindex] = 0;
+ tempFloatBufferA[pindex] = 0;
}
}
+
+ static float EdgeSphereColliderDetection(
+ ref float3x2 nextPosE,
+ in float2 radiusE,
+ in AABB aabbE,
+ float cfr,
+ in ColliderManager.WorkData cwork,
+ out float3 normal
+ )
+ {
+ // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
+ normal = 0;
+
+ //=========================================================
+ // AABB判定
+ //=========================================================
+ if (aabbE.Overlaps(cwork.aabb) == false)
+ return float.MaxValue;
+
+ // コライダー情報
+ float3 coldpos = cwork.oldPos.c0;
+ float3 cpos = cwork.nextPos.c0;
+ float cradius = cwork.radius.x;
+
+ //=========================================================
+ // 衝突判定
+ //=========================================================
+ // 移動前球に対する線分の最近接点
+ float s;
+ s = MathUtility.ClosestPtPointSegmentRatio(coldpos, nextPosE.c0, nextPosE.c1);
+ float3 c = math.lerp(nextPosE.c0, nextPosE.c1, s);
+
+ // 最近接点の距離
+ var v = c - coldpos;
+ float clen = math.length(v);
+ if (clen < 1e-09f)
+ return float.MaxValue;
+
+ // 押し出し法線
+ float3 n = v / clen;
+ normal = n;
+
+ // 変位
+ float3 db = cpos - coldpos;
+
+ // 変位をnに投影して距離チェック
+ float l1 = math.dot(n, db);
+ float l = clen - l1;
+
+ // 厚み
+ float rA = math.lerp(radiusE.x, radiusE.y, s);
+ float rB = cradius;
+ float thickness = rA + rB;
+
+ // 接触判定
+ if (l > (thickness + cfr))
+ return float.MaxValue;
+
+ //=========================================================
+ // 衝突解決
+ //=========================================================
+ // 接触法線に現在の距離を投影させる
+ v = c - cpos;
+ l = math.dot(n, v);
+ if (l > thickness)
+ {
+ // 接触なし
+ // 接触面までの距離を返す
+ return l - thickness;
+ }
+
+ // 離す距離
+ float C = thickness - l;
+
+ // エッジのみを引き離す
+ //float b0 = 1.0f - t;
+ //float b1 = t;
+ float2 b = new float2(1.0f - s, s);
+
+ //float3 grad0 = n * b0;
+ //float3 grad1 = n * b1;
+ float3x2 grad = new float3x2(n * b.x, n * b.y);
+
+ //float S = b0 * b0 + b1 * b1;
+ float S = math.dot(b, b);
+ if (S == 0.0f)
+ return float.MaxValue;
+
+ S = C / S;
+
+ //float3 corr0 = S * grad0;
+ //float3 corr1 = S * grad1;
+ float3x2 corr = grad * S;
+
+ //=========================================================
+ // 反映
+ //=========================================================
+ nextPosE += corr;
+
+ // 押し出し距離を返す
+ return -C;
+ }
+
+ static float EdgeCapsuleColliderDetection(
+ ref float3x2 nextPosE,
+ in float2 radiusE,
+ in AABB aabbE,
+ float cfr,
+ in ColliderManager.WorkData cwork,
+ out float3 normal
+ )
+ {
+ // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
+ normal = 0;
+
+ //=========================================================
+ // AABB判定
+ //=========================================================
+ if (aabbE.Overlaps(cwork.aabb) == false)
+ return float.MaxValue;
+
+ // コライダー情報
+ float3 soldpos = cwork.oldPos.c0;
+ float3 eoldpos = cwork.oldPos.c1;
+ float3 spos = cwork.nextPos.c0;
+ float3 epos = cwork.nextPos.c1;
+ float sr = cwork.radius.x;
+ float er = cwork.radius.y;
+
+ //=========================================================
+ // 衝突判定
+ //=========================================================
+ // 移動前の2つの線分の最近接点
+ float s, t;
+ float3 cA, cB;
+ float csqlen = MathUtility.ClosestPtSegmentSegment(nextPosE.c0, nextPosE.c1, soldpos, eoldpos, out s, out t, out cA, out cB);
+ float clen = math.sqrt(csqlen); // 最近接点の距離
+ if (clen < 1e-09f)
+ return float.MaxValue;
+
+ // 押出法線
+ var v = cA - cB;
+ float3 n = v / clen;
+ normal = n;
+
+#if !MC2_DISABLE_EDGE_COLLISION_EXTENSION
+ // ★カプセル半径を考慮した補正
+ // これまでのエッジ-カプセル判定はカプセルの半径が始点と終点で同じであることが前提となっていた
+ // そのためカプセルの始点と終点の半径が異なると間違った衝突判定が行われてしまい、それが原因で大きな振動が発生していた
+ // (これはBoneClothのようにカプセルエッジよりメッシュエッジのほうが長い場合に顕著になる)
+ // そこで始点と終点の半径が異なる場合は、最初の計算の最近接点方向からカプセルエッジを半径分シフトし、
+ // それをもとに再度エッジ-エッジ判定を行うように修正した
+ // これは完璧ではないがおおよそ理想的な判定を行うようになり、また振動の問題も大幅に解決できる
+ // (ただし小刻みな振動はまだ発生することがある)
+ if (sr != er)
+ {
+ // 押し出し法線方向にカプセル半径を考慮してカプセルの中心線をシフトさせる
+ float3 soldpos2 = soldpos + n * sr;
+ float3 eoldpos2 = eoldpos + n * er;
+
+ // この線分で再び最近接点(s/t)を計算する
+ MathUtility.ClosestPtSegmentSegment2(nextPosE.c0, nextPosE.c1, soldpos2, eoldpos2, out s, out t);
+
+ // 最終的にはこのシフト後のsとtを利用するように結果を書き換える
+ cA = math.lerp(nextPosE.c0, nextPosE.c1, s);
+ cB = math.lerp(soldpos, eoldpos, t);
+ v = cA - cB;
+ clen = math.length(v);
+ n = v / clen;
+ normal = n;
+ }
+#endif
+
+ // 変位
+ float3 dB0 = spos - soldpos;
+ float3 dB1 = epos - eoldpos;
+
+
+ // 最近接点での変位
+ float3 db = math.lerp(dB0, dB1, t);
+
+ // 変位da,dbをnに投影して距離チェック
+ float l1 = math.dot(n, db);
+ float l = clen - l1;
+
+ // 厚み
+ float rA = math.lerp(radiusE.x, radiusE.y, s);
+ float rB = math.lerp(sr, er, t);
+ float thickness = rA + rB;
+
+ // 接触判定
+ if (l > (thickness + cfr))
+ return float.MaxValue;
+
+ //=========================================================
+ // 衝突解決
+ //=========================================================
+ // 接触法線に現在の距離を投影させる
+ var d = math.lerp(spos, epos, t);
+ v = cA - d;
+ l = math.dot(n, v);
+ //Debug.Log($"l:{l}");
+ if (l > thickness)
+ {
+ // 接触なし
+ // 接触面までの距離を返す
+ return l - thickness;
+ }
+
+ // 離す距離
+ float C = thickness - l;
+ //Debug.Log($"C:{C}");
+
+ // エッジのみを引き離す
+ //float b0 = 1.0f - s;
+ //float b1 = s;
+ float2 b = new float2(1.0f - s, s);
+
+ //float3 grad0 = n * b0;
+ //float3 grad1 = n * b1;
+ float3x2 grad = new float3x2(n * b.x, n * b.y);
+
+ //float S = invMass0 * b0 * b0 + invMass1 * b1 * b1;
+ float S = math.dot(b, b);
+ if (S == 0.0f)
+ return float.MaxValue;
+
+ S = C / S;
+
+ //float3 corr0 = S * invMass0 * grad0;
+ //float3 corr1 = S * invMass1 * grad1;
+ float3x2 corr = grad * S;
+
+ //=========================================================
+ // 反映
+ //=========================================================
+ nextPosE += corr;
+
+ // 押し出し距離を返す
+ return -C;
+ }
+
+ static float EdgePlaneColliderDetection(
+ ref float3x2 nextPosE,
+ in float2 radiusE,
+ in ColliderManager.WorkData cwork,
+ out float3 normal
+ )
+ {
+ // ★たとえ接触していなくともコライダーまでの距離と法線を返さなければならない!
+
+ // コライダー情報
+ var cpos = cwork.nextPos.c0;
+ var n = cwork.oldPos.c0; // ここに押し出し法線
+
+ // 衝突法線
+ normal = n;
+
+ // c = 平面位置
+ // n = 平面方向
+ // 平面衝突判定と押し出し
+ // 平面との距離を返す(押し出しの場合は0.0)
+ float dist0 = MathUtility.IntersectPointPlaneDist(cpos + n * radiusE.x, n, nextPosE.c0, out nextPosE.c0);
+ float dist1 = MathUtility.IntersectPointPlaneDist(cpos + n * radiusE.y, n, nextPosE.c1, out nextPosE.c1);
+
+ return math.min(dist0, dist1);
+ }
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs.meta
index afa12400..7c3aa3d9 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/ColliderCollisionConstraint.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs
index acfbc158..5ffbd703 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs
@@ -4,9 +4,7 @@
using System;
using System.Collections.Generic;
using System.Text;
-using Unity.Burst;
using Unity.Collections;
-using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
@@ -85,9 +83,10 @@ namespace MagicaCloth2
///
/// 制約データ
///
- internal class ConstraintData : IValid
+ [System.Serializable]
+ public class ConstraintData : IValid
{
- internal ResultCode result;
+ public ResultCode result;
public uint[] indexArray;
public ushort[] dataArray;
@@ -151,7 +150,7 @@ namespace MagicaCloth2
/// 制約データの作成
///
///
- internal static ConstraintData CreateData(VirtualMesh proxyMesh, in ClothParameters parameters)
+ public static ConstraintData CreateData(VirtualMesh proxyMesh, in ClothParameters parameters)
{
var constraintData = new ConstraintData();
@@ -216,7 +215,7 @@ namespace MagicaCloth2
for (int l = 0; l < ecnt; l++)
{
int2 edge = proxyMesh.edges[l];
- var tset = proxyMesh.edgeToTriangles.ToFixedList128Bytes(edge);
+ var tset = proxyMesh.edgeToTriangles.MC2ToFixedList128Bytes(edge);
int tcnt = tset.Length;
if (tcnt < 2)
continue;
@@ -377,124 +376,55 @@ namespace MagicaCloth2
}
//=========================================================================================
- ///
- /// 制約の解決
- ///
- ///
- ///
- ///
- unsafe internal JobHandle SolverConstraint(JobHandle jobHandle)
- {
- var tm = MagicaManager.Team;
- var sm = MagicaManager.Simulation;
- var vm = MagicaManager.VMesh;
-
- var job = new DistanceConstraintJob()
- {
- simulationPower = MagicaManager.Time.SimulationPower,
-
- stepParticleIndexArray = sm.processingStepParticle.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- depthArray = vm.vertexDepths.GetNativeArray(),
-
- teamIdArray = sm.teamIdArray.GetNativeArray(),
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- basePosArray = sm.basePosArray.GetNativeArray(),
- velocityPosArray = sm.velocityPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
-
- //stepBasicPositionBuffer = sm.stepBasicPositionBuffer,
-
- indexArray = indexArray.GetNativeArray(),
- dataArray = dataArray.GetNativeArray(),
- distanceArray = distanceArray.GetNativeArray(),
- };
- jobHandle = job.Schedule(sm.processingStepParticle.GetJobSchedulePtr(), 32, jobHandle);
-
- return jobHandle;
- }
-
- ///
- /// 距離制約の解決
- ///
- [BurstCompile]
- struct DistanceConstraintJob : IJobParallelForDefer
- {
- public float4 simulationPower;
-
- [Unity.Collections.ReadOnly]
- public NativeArray stepParticleIndexArray;
-
+ // Solver
+ //=========================================================================================
+ internal static void SolverConstraint(
+ DataChunk chunk,
+ float4 simulationPower,
// team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
-
+ ref TeamManager.TeamData tdata,
+ ref ClothParameters param,
// vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray depthArray;
-
+ ref NativeArray attributes,
+ ref NativeArray depthArray,
// particle
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray basePosArray;
- [NativeDisableParallelForRestriction]
- public NativeArray velocityPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray frictionArray;
-
- // buffer
- //[Unity.Collections.ReadOnly]
- //public NativeArray stepBasicPositionBuffer;
-
+ ref NativeArray nextPosArray,
+ ref NativeArray basePosArray,
+ ref NativeArray velocityPosArray,
+ ref NativeArray frictionArray,
// constrants
- [Unity.Collections.ReadOnly]
- public NativeArray indexArray;
- [Unity.Collections.ReadOnly]
- public NativeArray dataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray distanceArray;
+ ref NativeArray indexArray,
+ ref NativeArray dataArray,
+ ref NativeArray distanceArray
+ )
+ {
+ var sc = tdata.distanceStartChunk;
+ var dc = tdata.distanceDataChunk;
+ if (sc.dataLength == 0)
+ return;
+ int c_start = sc.startIndex;
+ int d_start = dc.startIndex;
- // ステップ有効パーティクルごと
- public void Execute(int index)
+ // 復元を基本姿勢で行うかアニメーション後の姿勢で行うかの判定
+ float blendRatio = tdata.animationPoseRatio;
+
+ // スケール倍率
+ float scl = tdata.InitScale * tdata.scaleRatio;
+
+ bool isSpring = tdata.IsSpring;
+
+ // パーティクルごと
+ int p_start = tdata.particleChunk.startIndex;
+ int pindex = p_start + chunk.startIndex;
+ //int pindex = p_start;
+ int v_start = tdata.proxyCommonChunk.startIndex;
+ int vindex = v_start + chunk.startIndex;
+ //int vindex = v_start;
+ int dataIndex = chunk.startIndex;
+ //int dataIndex = 0;
+ //for (int k = 0; k < tdata.particleChunk.dataLength; k++, pindex++, vindex++, dataIndex++)
+ for (int k = 0; k < chunk.dataLength; k++, pindex++, vindex++, dataIndex++)
{
- // pindexのチームは有効であることが保証されている
- int pindex = stepParticleIndexArray[index];
-
- int teamId = teamIdArray[pindex];
- var tdata = teamDataArray[teamId];
- var parameter = parameterArray[teamId];
-
- // 復元を基本姿勢で行うかアニメーション後の姿勢で行うかの判定
- float blendRatio = tdata.animationPoseRatio;
-
- // スケール倍率
- float scl = tdata.InitScale * tdata.scaleRatio;
-
- int p_start = tdata.particleChunk.startIndex;
- int l_index = pindex - p_start;
-
- var sc = tdata.distanceStartChunk;
- var dc = tdata.distanceDataChunk;
-
- if (sc.dataLength == 0)
- return;
-
- int c_start = sc.startIndex;
- int d_start = dc.startIndex;
- int v_start = tdata.proxyCommonChunk.startIndex;
- int vindex = v_start + l_index;
-
// パーティクル情報
var nextPos = nextPosArray[pindex];
var attr = attributes[vindex];
@@ -502,36 +432,31 @@ namespace MagicaCloth2
float friction = frictionArray[pindex];
if (attr.IsInvalid())
- return;
+ continue;
// Spring利用中は固定も通す
- bool isSpring = tdata.IsSpring;
if (attr.IsDontMove() && isSpring == false)
- return;
+ continue;
// 固定点の重量
float fixMass = isSpring ? 10.0f : 50.0f;
// 重量
// BoneSpringでは固定点の重量加算を行わない
- //float invMass = MathUtility.CalcInverseMass(friction, depth, attr.IsDontMove() && isSpring == false);
float invMass = MathUtility.CalcInverseMass(friction, depth, attr.IsDontMove(), fixMass);
- //float invMass = isSpring && attr.IsDontMove() ? 1.0f / 2.0f : MathUtility.CalcInverseMass(friction, depth, attr.IsDontMove());
// 基本剛性
- float stiffness = parameter.distanceConstraint.restorationStiffness.EvaluateCurveClamp01(depth);
- //stiffness *= simulationPower;
- //stiffness *= (simulationPower * simulationPower);
+ float stiffness = param.distanceConstraint.restorationStiffness.MC2EvaluateCurveClamp01(depth);
stiffness *= simulationPower.y;
- var pack = indexArray[c_start + l_index];
+ //var pack = indexArray[c_start + k];
+ var pack = indexArray[c_start + dataIndex];
DataUtility.Unpack12_20(pack, out int dcnt, out int dstart);
if (dcnt > 0)
{
// 基準座標を切り替え
float3 basePos = basePosArray[pindex];
- //float3 basicPos = stepBasicPositionBuffer[pindex];
float3 addPos = 0;
int addCnt = 0;
@@ -550,22 +475,18 @@ namespace MagicaCloth2
int tvindex = v_start + t_l_index;
var t_nextPos = nextPosArray[tpindex];
float3 t_basePos = basePosArray[tpindex];
- //float3 t_basicPos = stepBasicPositionBuffer[tpindex];
float t_depth = depthArray[tvindex];
float t_friction = frictionArray[tpindex];
var t_attr = attributes[tvindex];
// 重量
// BoneSpringでは固定点の重量加算を行わない
- //float t_invMass = MathUtility.CalcInverseMass(t_friction, t_depth, t_attr.IsDontMove() && isSpring == false);
float t_invMass = MathUtility.CalcInverseMass(t_friction, t_depth, t_attr.IsDontMove(), fixMass);
- //float t_invMass = isSpring && t_attr.IsDontMove() ? 1.0f / 2.0f : MathUtility.CalcInverseMass(t_friction, t_depth, t_attr.IsDontMove());
// 復元する長さ
// !Distance制約は初期化時に保存した距離を見るようにしないと駄目
// フラグにより初期値かアニメーション後の姿勢かを切り替える
float restLength = math.lerp(math.abs(restDist) * scl, math.distance(basePos, t_basePos), blendRatio);
- //float restLength = math.distance(basicPos, t_basicPos);
var v = t_nextPos - nextPos;
@@ -595,7 +516,7 @@ namespace MagicaCloth2
nextPosArray[pindex] = nextPos;
// 速度影響
- float attn = parameter.distanceConstraint.velocityAttenuation;
+ float attn = param.distanceConstraint.velocityAttenuation;
velocityPosArray[pindex] = velocityPosArray[pindex] + addPos * attn;
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs.meta
index 36511876..2fec340c 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/DistanceConstraint.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs
index 066b91b1..02892b47 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs
@@ -39,6 +39,28 @@ namespace MagicaCloth2
[System.Serializable]
public class SerializeData : IDataValidate
{
+ ///
+ /// Anchor that cancels inertia.
+ /// Anchor translation and rotation are excluded from simulation.
+ /// This is useful if your character rides a vehicle.
+ /// 慣性を打ち消すアンカー
+ /// アンカーの移動と回転はシミュレーションから除外されます
+ /// これはキャラクターが乗り物に乗る場合に便利です
+ /// [OK] Runtime changes.
+ /// [NG] Export/Import with Presets
+ ///
+ public Transform anchor;
+
+ ///
+ /// Anchor Influence (0.0 ~ 1.0)
+ /// アンカーの影響(0.0 ~ 1.0)
+ /// [OK] Runtime changes.
+ /// [NG] Export/Import with Presets
+ ///
+ [Range(0.0f, 1.0f)]
+ public float anchorInertia;
+
+
///
/// World Influence (0.0 ~ 1.0).
/// ワールド移動影響(0.0 ~ 1.0)
@@ -49,6 +71,15 @@ namespace MagicaCloth2
[Range(0.0f, 1.0f)]
public float worldInertia;
+ ///
+ /// World Influence Smoothing (0.0 ~ 1.0).
+ /// ワールド移動影響平滑化(0.0 ~ 1.0)
+ /// [OK] Runtime changes.
+ /// [OK] Export/Import with Presets
+ ///
+ [Range(0.0f, 1.0f)]
+ public float movementInertiaSmoothing;
+
///
/// World movement speed limit (m/s).
/// ワールド移動速度制限(m/s)
@@ -144,7 +175,12 @@ namespace MagicaCloth2
public SerializeData()
{
+ anchor = null;
+ anchorInertia = 0.0f;
worldInertia = 1.0f;
+ //movementInertiaSmoothing = 0.65f; // ->0.0524
+ //movementInertiaSmoothing = 0.5f; // ->0.13375
+ movementInertiaSmoothing = 0.4f;
movementSpeedLimit = new CheckSliderSerializeData(true, 5.0f);
rotationSpeedLimit = new CheckSliderSerializeData(true, 720.0f);
localInertia = 1.0f;
@@ -162,7 +198,10 @@ namespace MagicaCloth2
{
return new SerializeData()
{
+ anchor = anchor,
+ anchorInertia = anchorInertia,
worldInertia = worldInertia,
+ movementInertiaSmoothing = movementInertiaSmoothing,
movementSpeedLimit = movementSpeedLimit.Clone(),
rotationSpeedLimit = rotationSpeedLimit.Clone(),
localInertia = localInertia,
@@ -179,7 +218,9 @@ namespace MagicaCloth2
public void DataValidate()
{
+ anchorInertia = Mathf.Clamp01(anchorInertia);
worldInertia = Mathf.Clamp01(worldInertia);
+ movementInertiaSmoothing = Mathf.Clamp01(movementInertiaSmoothing);
movementSpeedLimit.DataValidate(0.0f, Define.System.MaxMovementSpeedLimit);
rotationSpeedLimit.DataValidate(0.0f, Define.System.MaxRotationSpeedLimit);
localInertia = Mathf.Clamp01(localInertia);
@@ -195,18 +236,30 @@ namespace MagicaCloth2
public struct InertiaConstraintParams
{
+ ///
+ /// アンカー影響率(0.0 ~ 1.0)
+ ///
+ public float anchorInertia;
+
///
/// ワールド慣性影響(0.0 ~ 1.0)
///
public float worldInertia;
+ ///
+ /// ワールド慣性スムージング率(0.0 ~ 1.0)
+ ///
+ public float movementInertiaSmoothing;
+
///
/// ワールド移動速度制限(m/s)
+ /// 無制限時は(-1)
///
public float movementSpeedLimit;
///
/// ワールド回転速度制限(deg/s)
+ /// 無制限時は(-1)
///
public float rotationSpeedLimit;
@@ -258,7 +311,9 @@ namespace MagicaCloth2
public void Convert(SerializeData sdata)
{
+ anchorInertia = sdata.anchorInertia;
worldInertia = sdata.worldInertia;
+ movementInertiaSmoothing = sdata.movementInertiaSmoothing;
movementSpeedLimit = sdata.movementSpeedLimit.GetValue(-1);
rotationSpeedLimit = sdata.rotationSpeedLimit.GetValue(-1);
localInertia = sdata.localInertia;
@@ -277,8 +332,26 @@ namespace MagicaCloth2
///
/// センタートランスフォームのデータ
///
+ [System.Serializable]
public struct CenterData
{
+ ///
+ /// 現在のアンカー姿勢
+ ///
+ public float3 anchorPosition;
+ public quaternion anchorRotation;
+
+ ///
+ /// 前フレームのアンカー姿勢
+ ///
+ public float3 oldAnchorPosition;
+ public quaternion oldAnchorRotation;
+
+ ///
+ /// アンカー空間でのコンポーネントのローカル座標
+ ///
+ public float3 anchorComponentLocalPosition;
+
///
/// 参照すべきセンタートランスフォームインデックス
/// 同期時は同期先チームのもにになる
@@ -290,12 +363,14 @@ namespace MagicaCloth2
///
public float3 componentWorldPosition;
public quaternion componentWorldRotation;
+ public float3 componentWorldScale;
///
/// 前フレームのコンポーネント姿勢
///
public float3 oldComponentWorldPosition;
public quaternion oldComponentWorldRotation;
+ public float3 oldComponentWorldScale;
///
/// 現フレームのコンポーネント移動量
@@ -329,7 +404,7 @@ namespace MagicaCloth2
///
public float3 nowWorldPosition;
public quaternion nowWorldRotation;
- public float3 nowWorldScale; // ※現在未使用
+ //public float3 nowWorldScale; // ※現在未使用
///
/// 前回ステップでの姿勢
@@ -395,10 +470,26 @@ namespace MagicaCloth2
///
public float3 initLocalGravityDirection;
+ ///
+ /// スムージングされた現在のワールド慣性速度ベクトル
+ ///
+ public float3 smoothingVelocity; // (m/s)
+
+ ///
+ /// マイナススケールによる反転を打ち消すための変換マトリックス
+ /// センター空間
+ ///
+ public float4x4 negativeScaleMatrix;
+
internal void Initialize()
{
+ anchorRotation = quaternion.identity;
+ oldAnchorRotation = quaternion.identity;
+
componentWorldRotation = quaternion.identity;
+ componentWorldScale = 1;
oldComponentWorldRotation = quaternion.identity;
+ oldComponentWorldScale = 1;
frameComponentShiftRotation = quaternion.identity;
frameWorldRotation = quaternion.identity;
@@ -412,6 +503,7 @@ namespace MagicaCloth2
///
/// 制約データ
///
+ [System.Serializable]
public class ConstraintData
{
public ResultCode result;
@@ -450,7 +542,7 @@ namespace MagicaCloth2
/// 制約データの作成
///
///
- internal static ConstraintData CreateData(VirtualMesh proxyMesh, in ClothParameters parameters)
+ public static ConstraintData CreateData(VirtualMesh proxyMesh, in ClothParameters parameters)
{
var constraintData = new ConstraintData();
@@ -489,7 +581,7 @@ namespace MagicaCloth2
// 初期センター姿勢からローカル重力方向を算出する
var rot = MathUtility.ToRotation(math.normalize(nor), math.normalize(tan));
var irot = math.inverse(rot);
- localGravityDirection = math.mul(irot, parameters.gravityDirection);
+ localGravityDirection = math.mul(irot, parameters.worldGravityDirection);
}
constraintData.initLocalGravityDirection = localGravityDirection;
@@ -519,12 +611,13 @@ namespace MagicaCloth2
// 初期化時のローカル重力方向
cdata.initLocalGravityDirection = cprocess.inertiaConstraintData.initLocalGravityDirection;
+ //Debug.Log($"[{cprocess.TeamId}] initLocalGravityDirection:{cdata.initLocalGravityDirection}");
// 固定点リスト
var c = new DataChunk();
- if (cprocess.ProxyMesh.CenterFixedPointCount > 0)
+ if (cprocess.ProxyMeshContainer.shareVirtualMesh.CenterFixedPointCount > 0)
{
- c = fixedArray.AddRange(cprocess.ProxyMesh.centerFixedList);
+ c = fixedArray.AddRange(cprocess.ProxyMeshContainer.shareVirtualMesh.centerFixedList);
}
tdata.fixedDataChunk = c;
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs.meta
index 65f1cffa..b014fcfb 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/InertiaConstraint.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs
index 4df0e17d..d856e0d3 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs
@@ -2,9 +2,7 @@
// Copyright (c) 2023 MagicaSoft.
// https://magicasoft.jp
using System;
-using Unity.Burst;
using Unity.Collections;
-using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
@@ -134,97 +132,45 @@ namespace MagicaCloth2
}
//=========================================================================================
- ///
- /// 制約の解決
- ///
- ///
- ///
- unsafe internal JobHandle SolverConstraint(JobHandle jobHandle)
- {
- var tm = MagicaManager.Team;
- var sm = MagicaManager.Simulation;
- var vm = MagicaManager.VMesh;
-
- var job = new MotionConstraintJob()
- {
- stepParticleIndexArray = sm.processingStepMotionParticle.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- vertexDepths = vm.vertexDepths.GetNativeArray(),
-
- teamIdArray = sm.teamIdArray.GetNativeArray(),
- basePosArray = sm.basePosArray.GetNativeArray(),
- baseRotArray = sm.baseRotArray.GetNativeArray(),
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- velocityPosArray = sm.velocityPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
- collisionNormalArray = sm.collisionNormalArray.GetNativeArray(),
- };
- jobHandle = job.Schedule(sm.processingStepMotionParticle.GetJobSchedulePtr(), 32, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct MotionConstraintJob : IJobParallelForDefer
- {
- [Unity.Collections.ReadOnly]
- public NativeArray stepParticleIndexArray;
-
+ // Solver
+ //=========================================================================================
+ internal static void SolverConstraint(
+ DataChunk chunk,
// team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
-
+ ref TeamManager.TeamData tdata,
+ ref ClothParameters param,
// vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexDepths;
-
+ ref NativeArray attributes,
+ ref NativeArray vertexDepths,
// particle
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [Unity.Collections.ReadOnly]
- public NativeArray basePosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray baseRotArray;
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
- [NativeDisableParallelForRestriction]
- public NativeArray velocityPosArray;
- [NativeDisableParallelForRestriction]
- public NativeArray frictionArray;
- [NativeDisableParallelForRestriction]
- public NativeArray collisionNormalArray;
+ ref NativeArray basePosArray,
+ ref NativeArray baseRotArray,
+ ref NativeArray nextPosArray,
+ ref NativeArray velocityPosArray,
+ ref NativeArray frictionArray,
+ ref NativeArray collisionNormalArray
+ )
+ {
+ if (param.motionConstraint.useMaxDistance == false && param.motionConstraint.useBackstop == false)
+ return;
+ // stiffness
+ float stiffness = param.motionConstraint.stiffness;
- public void Execute(int index)
+ float backstopRadius = param.motionConstraint.backstopRadius;
+
+ // パーティクルごと
+ //int pindex = tdata.particleChunk.startIndex;
+ //int vindex = tdata.proxyCommonChunk.startIndex;
+ int pindex = tdata.particleChunk.startIndex + chunk.startIndex;
+ int vindex = tdata.proxyCommonChunk.startIndex + chunk.startIndex;
+ //for (int k = 0; k < tdata.particleChunk.dataLength; k++, pindex++, vindex++)
+ for (int k = 0; k < chunk.dataLength; k++, pindex++, vindex++)
{
- // pindexのチームは有効であることが保証されている
- int pindex = stepParticleIndexArray[index];
-
- int teamId = teamIdArray[pindex];
- var tdata = teamDataArray[teamId];
- var param = parameterArray[teamId];
- var motionParam = param.motionConstraint;
- var normalAxis = param.normalAxis;
- if (motionParam.useMaxDistance == false && motionParam.useBackstop == false)
- return;
-
- int p_start = tdata.particleChunk.startIndex;
- int l_index = pindex - p_start;
- int v_start = tdata.proxyCommonChunk.startIndex;
- int vindex = v_start + l_index;
-
// 移動パーティクルのみ
var attr = attributes[vindex];
if (attr.IsMove() == false)
- return;
+ continue;
var nextPos = nextPosArray[pindex];
var basePos = basePosArray[pindex];
@@ -233,17 +179,13 @@ namespace MagicaCloth2
// !MaxDistanceとBackstop制約は常にアニメーション姿勢(basePose)から計算されるので注意!
// !そのためAnimationBlendRatioは影響しない。
- // stiffness
- float stiffness = motionParam.stiffness;
-
// 適用頂点属性チェック
if (attr.IsMotion())
{
var opos = nextPos;
// パーティクル半径
- float radius = math.max(param.radiusCurveData.EvaluateCurve(depth), 0.0001f); // safe
- //radius *= tdata.scaleRatio;
+ float radius = math.max(param.radiusCurveData.MC2EvaluateCurve(depth), 0.0001f); // safe
// 摩擦影響距離
float cfr = radius * 1.0f;
@@ -256,7 +198,7 @@ namespace MagicaCloth2
//=========================================================
var baseRot = baseRotArray[pindex];
float3 dir = math.up();
- switch (normalAxis)
+ switch (param.normalAxis)
{
case ClothNormalAxis.Right:
dir = math.right();
@@ -282,9 +224,9 @@ namespace MagicaCloth2
//=========================================================
// Max Distance
//=========================================================
- if (motionParam.useMaxDistance)
+ if (param.motionConstraint.useMaxDistance)
{
- float maxDistance = motionParam.maxDistanceCurveData.EvaluateCurve(depth);
+ float maxDistance = param.motionConstraint.maxDistanceCurveData.MC2EvaluateCurve(depth);
//var cen = basePos + dir * (motionParam.maxDistanceOffset * maxDistance);
var cen = basePos;
var v = MathUtility.ClampVector(nextPos - cen, maxDistance);
@@ -294,10 +236,9 @@ namespace MagicaCloth2
//=========================================================
// Backstop
//=========================================================
- if (motionParam.useBackstop)
+ if (param.motionConstraint.useBackstop)
{
- float backstopRadius = motionParam.backstopRadius;
- float backstopDistance = motionParam.backstopDistanceCurveData.EvaluateCurve(depth);
+ float backstopDistance = param.motionConstraint.backstopDistanceCurveData.MC2EvaluateCurve(depth);
if (backstopRadius > 0.0f)
{
// バックストップは法線逆方向
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs.meta
index fa88e762..af72c547 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/MotionConstraint.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs
index 84ffa613..8388a90e 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs
@@ -1,5 +1,5 @@
// Magica Cloth 2.
-// Copyright (c) 2023 MagicaSoft.
+// Copyright (c) 2025 MagicaSoft.
// https://magicasoft.jp
using System;
using System.Runtime.CompilerServices;
@@ -13,7 +13,7 @@ using UnityEngine;
namespace MagicaCloth2
{
- public class SelfCollisionConstraint : IDisposable
+ public partial class SelfCollisionConstraint : IDisposable
{
public enum SelfCollisionMode
{
@@ -116,6 +116,10 @@ namespace MagicaCloth2
}
//=========================================================================================
+ ///
+ /// プリミティブ
+ /// Point/Edge/Triangleの管理
+ ///
public const uint KindPoint = 0;
public const uint KindEdge = 1;
public const uint KindTriangle = 2;
@@ -127,31 +131,41 @@ namespace MagicaCloth2
public const uint Flag_AllFix = 0x20000000;
public const uint Flag_Ignore = 0x40000000; // 無効もしくは無視頂点が含まれる
public const uint Flag_Enable = 0x80000000; // 接触判定有効
+ public const uint Flag_Intersect0 = 0x00000001;
+ public const uint Flag_Intersect1 = 0x00000002;
+ public const uint Flag_Intersect2 = 0x00000004;
- struct Primitive
+ public const uint Flag_FixIntersect0 = (Flag_Fix0 | Flag_Intersect0);
+ public const uint Flag_FixIntersect1 = (Flag_Fix1 | Flag_Intersect1);
+ public const uint Flag_FixIntersect2 = (Flag_Fix2 | Flag_Intersect2);
+
+ unsafe internal struct Primitive : IComparable
{
///
- /// フラグとチームID
- /// 上位8bit = フラグ
- /// 下位24bit = チームID
+ /// フラグ
///
- public uint flagAndTeamId;
+ public uint flag;
///
- /// ソートリストへのインデックス(グローバル)
- ///
- public int sortIndex;
-
- ///
- /// プリミティグを構成するパーティクルインデックス
+ /// プリミティブを構成するパーティクルインデックス
+ /// 不要な軸は(-1)が設定されている
///
public int3 particleIndices;
- public float3x3 nextPos;
- public float3x3 oldPos;
- //public float3x3 basePos;
public float3 invMass;
+ ///
+ /// プリミティブAABB
+ ///
+ public AABB aabb;
+
+ ///
+ /// UniformGird座標
+ ///
+ public int3 grid;
+
+ public float depth;
+
///
/// 厚み
///
@@ -160,36 +174,13 @@ namespace MagicaCloth2
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsIgnore()
{
- return (flagAndTeamId & Flag_Ignore) != 0;
+ return (flag & Flag_Ignore) != 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool HasParticle(int p)
+ public bool IsAllFix()
{
- return p >= 0 && math.all(particleIndices - p) == false;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public uint GetKind()
- {
- return (flagAndTeamId & Flag_KindMask) >> 24;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public int GetTeamId()
- {
- return (int)(flagAndTeamId & 0xffffff);
- }
-
- ///
- /// 解決時のthicknessを計算する
- ///
- ///
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public float GetSolveThickness(in Primitive pri)
- {
- return thickness + pri.thickness;
+ return (flag & Flag_AllFix) != 0;
}
///
@@ -198,53 +189,104 @@ namespace MagicaCloth2
///
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool AnyParticle(in Primitive pri)
+ public bool AnyParticle(ref Primitive pri)
{
- for (int i = 0; i < 3; i++)
+ uint kind = ((flag & Flag_KindMask) >> 24) + 1;
+
+ for (int i = 0; i < kind; i++)
{
int p = particleIndices[i];
- if (p >= 0)
- {
- if (math.all(pri.particleIndices - p) == false)
- return true;
- }
+
+ // 入力すべてが非0ならtrue
+ if (math.all(pri.particleIndices - p) == false)
+ return true;
}
+
return false;
}
- }
- ExNativeArray primitiveArray;
-
- struct SortData : IComparable
- {
- ///
- /// フラグとチームID
- /// 上位8bit = フラグ
- /// 下位24bit = チームID
- ///
- public uint flagAndTeamId;
///
- /// プリミティブインデックス(グローバル)
+ /// ソート用
+ /// グリッドX->Y->Zの順でソート
///
- public int primitiveIndex;
-
- public float2 firstMinMax;
- public float2 secondMinMax;
- public float2 thirdMinMax;
-
- public int CompareTo(SortData other)
+ ///
+ ///
+ public int CompareTo(Primitive other)
{
- return (int)math.sign(firstMinMax.x - other.firstMinMax.x);
+ if (grid.x != other.grid.x)
+ return grid.x - other.grid.x;
+ if (grid.y != other.grid.y)
+ return grid.y - other.grid.y;
+ return grid.z - other.grid.z;
}
+ }
+ internal ExNativeArray primitiveArrayB;
+
+ ///
+ /// グリッド
+ /// プリミティブ検出用のグリッド情報
+ ///
+ internal struct GridInfo : IComparable
+ {
+ // このグリッドのハッシュ値
+ public int hash;
+
+ // このグリッドの開始プリミティブインデックス
+ public int start;
+
+ // このグリッドに格納されているプリミティブ数
+ public int count;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public uint GetKind()
+ public int CompareTo(GridInfo other)
{
- return (flagAndTeamId & Flag_KindMask) >> 24;
+ if (hash < other.hash)
+ return -1;
+ else if (hash > other.hash)
+ return 1;
+ else
+ return 0;
}
}
- ExNativeArray sortAndSweepArray;
+ internal ExNativeArray uniformGridStartCountBuffer;
+ ///
+ /// コンタクト
+ /// 衝突プリミティブペアの管理
+ ///
+ internal const byte ContactType_EdgeEdge = 0;
+ internal const byte ContactType_PointTriangle = 1;
+ internal const byte ContactType_TrianglePoint = 2;
+
+ internal struct ContactInfo
+ {
+ public int primitiveIndex0;
+ public int primitiveIndex1;
+ public byte contactType;
+ public byte enable;
+ public half thickness;
+ public half s;
+ public half t;
+ public half3 n;
+ }
+
+ internal NativeQueue contactQueue;
+ internal NativeList contactList;
+
+ ///
+ /// インターセクト
+ /// 絡まり防止のEdgeTriangleペアの管理
+ ///
+ internal struct IntersectInfo
+ {
+ public int2 edgeParticeIndices;
+ public int3 triangleParticleIndices;
+ }
+
+ internal NativeQueue intersectQueue;
+ internal NativeList intersectList;
+
+ //=========================================================================================
///
/// ポイントプリミティブ総数
///
@@ -261,87 +303,49 @@ namespace MagicaCloth2
public int TrianglePrimitiveCount { get; private set; } = 0;
//=========================================================================================
- internal struct EdgeEdgeContact
- {
- public uint flagAndTeamId0;
- public uint flagAndTeamId1;
- public half thickness;
- public half s;
- public half t;
- public half3 n;
- public half2 edgeInvMass0;
- public half2 edgeInvMass1;
- public int2 edgeParticleIndex0;
- public int2 edgeParticleIndex1;
-
- public override string ToString()
- {
- return $"EdgeEdge f0:{flagAndTeamId0:X}, f1:{flagAndTeamId1:X}, p0:{edgeParticleIndex0}, p1:{edgeParticleIndex1}, inv0:{edgeInvMass0}, inv1:{edgeInvMass1}";
- }
- }
- NativeQueue edgeEdgeContactQueue;
- NativeList edgeEdgeContactList;
-
- internal struct PointTriangleContact
- {
- public uint flagAndTeamId0; // point
- public uint flagAndTeamId1; // triangle
- public half thickness;
- public half sign; // 押出方向(-1/+1)
- public int pointParticleIndex;
- public int3 triangleParticleIndex;
- public half pointInvMass;
- public half3 triangleInvMass;
-
- public override string ToString()
- {
- return $"PointTriangle f0:{flagAndTeamId0:X}, f1:{flagAndTeamId1:X}, pp:{pointParticleIndex}, pt:{triangleParticleIndex}, pinv:{pointInvMass}, tinv:{triangleInvMass}";
- }
- }
- NativeQueue pointTriangleContactQueue;
- NativeList pointTriangleContactList;
-
///
/// 交差解決フラグ(パーティクルと連動)
///
- NativeArray intersectFlagArray;
+ internal NativeArray intersectFlagArray;
- public int IntersectCount { get; private set; } = 0;
+ internal int IntersectCount { get; private set; } = 0;
//=========================================================================================
public SelfCollisionConstraint()
{
- primitiveArray = new ExNativeArray(0, true);
- sortAndSweepArray = new ExNativeArray(0, true);
-
- edgeEdgeContactQueue = new NativeQueue(Allocator.Persistent);
- pointTriangleContactQueue = new NativeQueue(Allocator.Persistent);
- edgeEdgeContactList = new NativeList(Allocator.Persistent);
- pointTriangleContactList = new NativeList(Allocator.Persistent);
-
intersectFlagArray = new NativeArray(0, Allocator.Persistent);
+ primitiveArrayB = new ExNativeArray(0, true);
+ uniformGridStartCountBuffer = new ExNativeArray(0, true);
+ contactQueue = new NativeQueue(Allocator.Persistent);
+ contactList = new NativeList(Allocator.Persistent);
+ intersectQueue = new NativeQueue(Allocator.Persistent);
+ intersectList = new NativeList(Allocator.Persistent);
+
//Develop.DebugLog($"UseQueueCount:{UseQueueCount}");
}
public void Dispose()
{
- primitiveArray?.Dispose();
- primitiveArray = null;
-
- sortAndSweepArray?.Dispose();
- sortAndSweepArray = null;
-
PointPrimitiveCount = 0;
EdgePrimitiveCount = 0;
TrianglePrimitiveCount = 0;
- edgeEdgeContactQueue.Dispose();
- pointTriangleContactQueue.Dispose();
- edgeEdgeContactList.Dispose();
- pointTriangleContactList.Dispose();
+ intersectFlagArray.MC2DisposeSafe();
- intersectFlagArray.DisposeSafe();
+ primitiveArrayB?.Dispose();
+ primitiveArrayB = null;
+ uniformGridStartCountBuffer?.Dispose();
+ uniformGridStartCountBuffer = null;
+
+ if (contactQueue.IsCreated)
+ contactQueue.Dispose();
+ if (contactList.IsCreated)
+ contactList.Dispose();
+ if (intersectQueue.IsCreated)
+ intersectQueue.Dispose();
+ if (intersectList.IsCreated)
+ intersectList.Dispose();
IntersectCount = 0;
}
@@ -359,70 +363,11 @@ namespace MagicaCloth2
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"[SelfCollisionConstraint]");
- sb.AppendLine($" -primitiveArray:{primitiveArray.ToSummary()}");
- sb.AppendLine($" -sortAndSweepArray:{sortAndSweepArray.ToSummary()}");
-
- sb.AppendLine($" -edgeEdgeContactQueue:{(edgeEdgeContactQueue.IsCreated ? edgeEdgeContactQueue.Count : 0)}");
- sb.AppendLine($" -edgeEdgeContactList:{(edgeEdgeContactList.IsCreated ? edgeEdgeContactList.Length : 0)}");
- sb.AppendLine($" -pointTriangleContactQueue:{(pointTriangleContactQueue.IsCreated ? pointTriangleContactQueue.Count : 0)}");
- sb.AppendLine($" -pointTriangleContactList:{(pointTriangleContactList.IsCreated ? pointTriangleContactList.Length : 0)}");
sb.AppendLine($" -intersectFlagArray:{(intersectFlagArray.IsCreated ? intersectFlagArray.Length : 0)}");
return sb.ToString();
}
- //=========================================================================================
-#if false
- internal class ConstraintData : IValid
- {
- public ResultCode result;
-
- ///
- /// 同期先proxyMeshのlocalPosを自proxyMesh空間に変換するマトリックス
- ///
- public float4x4 syncToSelfMatrix;
-
- public bool IsValid()
- {
- return math.any(syncToSelfMatrix.c0);
- }
- }
-
- internal static ConstraintData CreateData(
- int teamId, TeamManager.TeamData teamData, VirtualMesh proxyMesh, in ClothParameters parameters,
- int syncTeamId, TeamManager.TeamData syncTeamData, VirtualMesh syncProxyMesh)
- {
- var constraintData = new ConstraintData();
-
- try
- {
- if (proxyMesh.VertexCount == 0)
- return null;
-
- var self2Params = parameters.selfCollisionConstraint2;
-
- // 同期チームとのFullMesh判定が必要な場合は、同期ProxyMeshのローカル頂点を時チームの座標空間に変換しておく
- //var syncMode = parameters.selfCollisionConstraint.syncMode;
- //if (syncTeamId > 0 && syncProxyMesh != null)
- //{
- // // 同期proxyMeshを自proxyMesh空間に変換するマトリックス
- // var toM = syncProxyMesh.CenterTransformTo(proxyMesh);
- // constraintData.syncToSelfMatrix = toM;
- //}
- }
- catch (Exception exception)
- {
- Debug.LogException(exception);
- constraintData.result.SetError(Define.Result.Constraint_CreateSelfCollisionException);
- }
- finally
- {
- }
-
- return constraintData;
- }
-#endif
-
//=========================================================================================
///
/// 制約データを登録する
@@ -464,6 +409,13 @@ namespace MagicaCloth2
// チームが消滅中かどうか
bool exit = tdata.flag.IsSet(TeamManager.Flag_Exit);
+ // sync解除
+ if (exit && tdata.syncTeamId != 0 && tm.ContainsTeamData(tdata.syncTeamId))
+ {
+ ref var stdata = ref tm.GetTeamDataRef(tdata.syncTeamId);
+ tm.RemoveSyncParent(ref stdata, teamId);
+ }
+
// 自身の状況を判定する
ref var parameter = ref tm.GetParametersRef(teamId);
var selfMode = exit ? SelfCollisionMode.None : parameter.selfCollisionConstraint.selfMode;
@@ -495,15 +447,15 @@ namespace MagicaCloth2
{
if (tdata.EdgeCount > 0)
{
- selfEdgeEdge = true;
useEdgePrimitive = true;
+ selfEdgeEdge = true;
}
if (tdata.TriangleCount > 0)
{
- selfPointTriangle = true;
- selfTrianglePoint = true;
usePointPrimitive = true;
useTrianglePrimitive = true;
+ selfPointTriangle = true;
+ selfTrianglePoint = true;
}
if (tdata.EdgeCount > 0 && tdata.TriangleCount > 0)
{
@@ -520,18 +472,18 @@ namespace MagicaCloth2
{
if (tdata.EdgeCount > 0 && stdata.EdgeCount > 0)
{
- syncEdgeEdge = true;
useEdgePrimitive = true;
+ syncEdgeEdge = true;
}
if (tdata.TriangleCount > 0)
{
- syncTrianglePoint = true;
useTrianglePrimitive = true;
+ syncTrianglePoint = true;
}
if (stdata.TriangleCount > 0)
{
- syncPointTriangle = true;
usePointPrimitive = true;
+ syncPointTriangle = true;
}
if (tdata.EdgeCount > 0 && stdata.TriangleCount > 0)
{
@@ -559,18 +511,18 @@ namespace MagicaCloth2
{
if (ptdata.EdgeCount > 0 && tdata.EdgeCount > 0)
{
- PsyncEdgeEdge = true;
useEdgePrimitive = true;
+ PsyncEdgeEdge = true;
}
if (ptdata.TriangleCount > 0)
{
- PsyncPointTriangle = true;
usePointPrimitive = true;
+ PsyncPointTriangle = true;
}
if (tdata.TriangleCount > 0)
{
- PsyncTrianglePoint = true;
useTrianglePrimitive = true;
+ PsyncTrianglePoint = true;
}
if (tdata.EdgeCount > 0 && ptdata.TriangleCount > 0)
{
@@ -613,17 +565,17 @@ namespace MagicaCloth2
{
// init
int pointCount = tdata.ParticleCount;
- tdata.selfPointChunk = primitiveArray.AddRange(pointCount);
- sortAndSweepArray.AddRange(pointCount);
+ tdata.selfPointChunk = primitiveArrayB.AddRange(pointCount);
+ uniformGridStartCountBuffer.AddRange(pointCount);
int start = tdata.selfPointChunk.startIndex;
- InitPrimitive(teamId, tdata, KindPoint, start, start, pointCount);
+ InitPrimitive(teamId, tdata, KindPoint, start, pointCount);
PointPrimitiveCount += pointCount;
}
else if (usePointPrimitive == false && tdata.selfPointChunk.IsValid)
{
// remove
- primitiveArray.Remove(tdata.selfPointChunk);
- sortAndSweepArray.Remove(tdata.selfPointChunk);
+ primitiveArrayB.Remove(tdata.selfPointChunk);
+ uniformGridStartCountBuffer.Remove(tdata.selfPointChunk);
PointPrimitiveCount -= tdata.selfPointChunk.dataLength;
tdata.selfPointChunk.Clear();
}
@@ -633,17 +585,17 @@ namespace MagicaCloth2
{
// init
int edgeCount = tdata.EdgeCount;
- tdata.selfEdgeChunk = primitiveArray.AddRange(edgeCount);
- sortAndSweepArray.AddRange(edgeCount);
+ tdata.selfEdgeChunk = primitiveArrayB.AddRange(edgeCount);
+ uniformGridStartCountBuffer.AddRange(edgeCount);
int start = tdata.selfEdgeChunk.startIndex;
- InitPrimitive(teamId, tdata, KindEdge, start, start, edgeCount);
+ InitPrimitive(teamId, tdata, KindEdge, start, edgeCount);
EdgePrimitiveCount += edgeCount;
}
else if (useEdgePrimitive == false && tdata.selfEdgeChunk.IsValid)
{
// remove
- primitiveArray.Remove(tdata.selfEdgeChunk);
- sortAndSweepArray.Remove(tdata.selfEdgeChunk);
+ primitiveArrayB.Remove(tdata.selfEdgeChunk);
+ uniformGridStartCountBuffer.Remove(tdata.selfEdgeChunk);
EdgePrimitiveCount -= tdata.selfEdgeChunk.dataLength;
tdata.selfEdgeChunk.Clear();
}
@@ -653,17 +605,17 @@ namespace MagicaCloth2
{
// init
int triangleCount = tdata.TriangleCount;
- tdata.selfTriangleChunk = primitiveArray.AddRange(triangleCount);
- sortAndSweepArray.AddRange(triangleCount);
+ tdata.selfTriangleChunk = primitiveArrayB.AddRange(triangleCount);
+ uniformGridStartCountBuffer.AddRange(triangleCount);
int start = tdata.selfTriangleChunk.startIndex;
- InitPrimitive(teamId, tdata, KindTriangle, start, start, triangleCount);
+ InitPrimitive(teamId, tdata, KindTriangle, start, triangleCount);
TrianglePrimitiveCount += triangleCount;
}
else if (useTrianglePrimitive == false && tdata.selfTriangleChunk.IsValid)
{
// remove
- primitiveArray.Remove(tdata.selfTriangleChunk);
- sortAndSweepArray.Remove(tdata.selfTriangleChunk);
+ primitiveArrayB.Remove(tdata.selfTriangleChunk);
+ uniformGridStartCountBuffer.Remove(tdata.selfTriangleChunk);
TrianglePrimitiveCount -= tdata.selfTriangleChunk.dataLength;
tdata.selfTriangleChunk.Clear();
}
@@ -683,27 +635,38 @@ namespace MagicaCloth2
}
// 同期対象に対して再帰する
- if (syncMode != SelfCollisionMode.None && tm.ContainsTeamData(tdata.syncTeamId))
+ if (tdata.syncTeamId != 0 && tm.ContainsTeamData(tdata.syncTeamId))
{
UpdateTeam(tdata.syncTeamId);
}
}
- void InitPrimitive(int teamId, TeamManager.TeamData tdata, uint kind, int startPrimitive, int startSort, int length)
+ ///
+ /// プリミティブ初期化
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ void InitPrimitive(int teamId, TeamManager.TeamData tdata, uint kind, int startPrimitive, int length)
{
+ var vm = MagicaManager.VMesh;
+
var job = new InitPrimitiveJob()
{
teamId = teamId,
tdata = tdata,
+
kind = kind,
startPrimitive = startPrimitive,
- startSort = startSort,
- edges = MagicaManager.VMesh.edges.GetNativeArray(),
- triangles = MagicaManager.VMesh.triangles.GetNativeArray(),
+ edges = vm.edges.GetNativeArray(),
+ triangles = vm.triangles.GetNativeArray(),
+ attributes = vm.attributes.GetNativeArray(),
+ vertexDepths = vm.vertexDepths.GetNativeArray(),
- primitiveArray = primitiveArray.GetNativeArray(),
- sortArray = sortAndSweepArray.GetNativeArray(),
+ primitiveArrayB = primitiveArrayB.GetNativeArray(),
};
job.Run(length); // ここではRun()で実行する
}
@@ -716,30 +679,29 @@ namespace MagicaCloth2
public uint kind;
public int startPrimitive;
- public int startSort;
// vmesh
[Unity.Collections.ReadOnly]
public NativeArray edges;
[Unity.Collections.ReadOnly]
public NativeArray triangles;
+ [Unity.Collections.ReadOnly]
+ public NativeArray attributes;
+ [Unity.Collections.ReadOnly]
+ public NativeArray vertexDepths;
[NativeDisableParallelForRestriction]
- public NativeArray primitiveArray;
- [NativeDisableParallelForRestriction]
- public NativeArray sortArray;
+ public NativeArray primitiveArrayB;
public void Execute(int index)
{
int pri_index = startPrimitive + index;
- int sort_index = startSort + index;
- var p = primitiveArray[pri_index];
- var s = sortArray[sort_index];
+ var p = primitiveArrayB[pri_index];
+ int pstart = tdata.particleChunk.startIndex;
// プリミティブを構成するパーティクルインデックス
int3 particleIndices = -1;
- int pstart = tdata.particleChunk.startIndex;
if (kind == KindPoint)
{
particleIndices[0] = pstart + index;
@@ -755,494 +717,16 @@ namespace MagicaCloth2
particleIndices.xyz = triangles[tstart + index] + pstart;
}
- p.flagAndTeamId = (uint)teamId | (kind << 24);
- p.sortIndex = sort_index;
- p.particleIndices = particleIndices;
-
- s.primitiveIndex = pri_index;
- s.flagAndTeamId = (uint)teamId;
-
- primitiveArray[pri_index] = p;
- sortArray[sort_index] = s;
- }
- }
-
- ///
- /// 作業バッファ更新
- ///
- internal void WorkBufferUpdate()
- {
- // 交差フラグバッファ
- if (IntersectCount > 0)
- {
- int pcnt = MagicaManager.Simulation.ParticleCount;
- intersectFlagArray.Resize(pcnt, options: NativeArrayOptions.ClearMemory);
- }
-
-#if MC2_DEBUG && false
- // debug
- Develop.DebugLog($"PointPrimitive:{PointPrimitiveCount}, EdgePrimitive:{EdgePrimitiveCount}, TrianglePrimitive:{TrianglePrimitiveCount}, Intersect:{IntersectCount}");
- if (edgeEdgeContactQueue.Count > 0 || pointTriangleContactQueue.Count > 0)
- Develop.DebugLog($"EdgeEdge Contact:{edgeEdgeContactQueue.Count}, PointTriangle Contact:{pointTriangleContactQueue.Count}");
- edgeEdgeContactQueue.Clear();
- pointTriangleContactQueue.Clear();
-#endif
-
- }
-
- ///
- /// ソート&スイープ配列をデータsdで二分探索しその開始インデックスを返す
- ///
- ///
- ///
- ///
- ///
- static unsafe int BinarySearchSortAndlSweep(ref NativeArray sortAndSweepArray, in SortData sd, in DataChunk chunk)
- {
- SortData* pt = (SortData*)sortAndSweepArray.GetUnsafeReadOnlyPtr();
- pt += chunk.startIndex;
- int sortIndex = NativeSortExtension.BinarySearch(pt, chunk.dataLength, sd);
- if (sortIndex < 0)
- {
- // インデックスが正の場合は値が正確に発見されたのでそのインデックスが返る
- // インデックスが負の場合は値が見つからずに最終的な探索インデックスが返る
- // この場合はそのインデックスを正に戻しそこから-1した場所が値の次のインデックスとなっている
- // 例:(-7) = 検索値はインデックス5と6の間
- sortIndex = math.max(-sortIndex - 1, 0);
- }
- sortIndex += chunk.startIndex;
-
- return sortIndex;
- }
-
- //=========================================================================================
- ///
- /// 制約の解決
- ///
- ///
- ///
- internal JobHandle SolverConstraint(int updateIndex, JobHandle jobHandle)
- {
- // 実行時セルフコリジョンの解決
- jobHandle = SolverRuntimeSelfCollision(updateIndex, jobHandle);
-
- // 絡まり解決
- jobHandle = SolveIntersect(jobHandle);
-
- return jobHandle;
- }
-
- ///
- /// 実行時セルフコリジョンの解決
- ///
- ///
- ///
- unsafe JobHandle SolverRuntimeSelfCollision(int updateIndex, JobHandle jobHandle)
- {
- if (HasPrimitive() == false)
- return jobHandle;
-
- // Broad phase ====================================================
- // コンタクトバッファ生成
- // !コンタクトバッファ生成は1フレームに1回しか実行しない
- // !ステップ2回目以降は各パーティクルが線形に移動するだけでコンタクト生成結果にあまり変化が無いためスキップさせる
- // !これは本来ならNGだがクオリティよりパフォーマンスを優先した実装となる
- // !そもそも毎ステップ生成したとしてもMagicaClothは反復が少ないので絡まるときは絡まる。
- // !MagicaClothではその絡まりを最後のSolveIntersect()で解くことに重点を置く
- if (updateIndex == 0)
- {
- // この生成が大変重い!
- jobHandle = SolverBroadPhase(jobHandle);
- }
- else
- {
- // !ステップ2回目以降はコンタクトバッファの内容に対して再度ブロードフェーズのみを実行する
- jobHandle = UpdateBroadPhase(jobHandle);
- }
-
- // Solver phase ====================================================
- // 接触の解決
- // !直列1回と同程度の堅牢さは並列では反復3~4回ほど必要
- var sm = MagicaManager.Simulation;
- for (int i = 0; i < Define.System.SelfCollisionSolverIteration; i++)
- {
- var solverEdgeEdgeJob = new SolverEdgeEdgeJob()
- {
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- edgeEdgeContactArray = edgeEdgeContactList.AsDeferredJobArray(),
- countArray = sm.countArray,
- sumArray = sm.sumArray,
- };
- jobHandle = solverEdgeEdgeJob.Schedule(edgeEdgeContactList, 16, jobHandle);
-
- var solverPointTriangleJob = new SolverPointTriangleJob()
- {
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- pointTriangleContactArray = pointTriangleContactList.AsDeferredJobArray(),
- countArray = sm.countArray,
- sumArray = sm.sumArray,
- };
- jobHandle = solverPointTriangleJob.Schedule(pointTriangleContactList, 16, jobHandle);
-
- // 集計
- const float attn = 0.0f; // 0.0f
- jobHandle = InterlockUtility.SolveAggregateBufferAndClear(sm.processingSelfParticle, attn, jobHandle);
- }
-
- return jobHandle;
- }
-
- ///
- /// コンタクトバッファ生成
- ///
- ///
- ///
- unsafe JobHandle SolverBroadPhase(JobHandle jobHandle)
- {
- var tm = MagicaManager.Team;
- var sm = MagicaManager.Simulation;
- var vm = MagicaManager.VMesh;
-
- // バッファクリア
- jobHandle = new ClearBufferJob()
- {
- edgeEdgeContactQueue = edgeEdgeContactQueue,
- pointTriangleContactQueue = pointTriangleContactQueue,
- }.Schedule(jobHandle);
-
- // プリミティブ更新 =======================================================
- if (PointPrimitiveCount > 0)
- {
- // PointTriangle
- var job2 = new UpdatePrimitiveJob()
- {
- kind = KindPoint,
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- depthArray = vm.vertexDepths.GetNativeArray(),
-
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- oldPosArray = sm.oldPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
- //stepBasicPositionBuffer = sm.stepBasicPositionBuffer,
-
- primitiveArray = primitiveArray.GetNativeArray(),
- sortAndSweepArray = sortAndSweepArray.GetNativeArray(),
-
- processingArray = sm.processingSelfPointTriangle.Buffer,
- };
- jobHandle = job2.Schedule(sm.processingSelfPointTriangle.GetJobSchedulePtr(), 16, jobHandle);
- }
- if (EdgePrimitiveCount > 0)
- {
- // EdgeEdge
- var job = new UpdatePrimitiveJob()
- {
- kind = KindEdge,
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- depthArray = vm.vertexDepths.GetNativeArray(),
-
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- oldPosArray = sm.oldPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
- //stepBasicPositionBuffer = sm.stepBasicPositionBuffer,
-
- primitiveArray = primitiveArray.GetNativeArray(),
- sortAndSweepArray = sortAndSweepArray.GetNativeArray(),
-
- processingArray = sm.processingSelfEdgeEdge.Buffer,
- };
- jobHandle = job.Schedule(sm.processingSelfEdgeEdge.GetJobSchedulePtr(), 16, jobHandle);
- }
- if (TrianglePrimitiveCount > 0)
- {
- // TrianglePoint
- var job = new UpdatePrimitiveJob()
- {
- kind = KindTriangle,
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- depthArray = vm.vertexDepths.GetNativeArray(),
-
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- oldPosArray = sm.oldPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
- //stepBasicPositionBuffer = sm.stepBasicPositionBuffer,
-
- primitiveArray = primitiveArray.GetNativeArray(),
- sortAndSweepArray = sortAndSweepArray.GetNativeArray(),
-
- processingArray = sm.processingSelfTrianglePoint.Buffer,
- };
- jobHandle = job.Schedule(sm.processingSelfTrianglePoint.GetJobSchedulePtr(), 16, jobHandle);
- }
-
- // sort ===========================================================
- // チームごと、およびpoint/edge/triangle別
- var sortJob = new SortJob()
- {
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- primitiveArray = primitiveArray.GetNativeArray(),
- sortAndSweepArray = sortAndSweepArray.GetNativeArray(),
- };
- jobHandle = sortJob.Schedule(tm.TeamCount * 3, 1, jobHandle); // 3 = (Point/Edge/Triangle)
-
- // Broad phase ====================================================
- // EdgeEdge
- if (EdgePrimitiveCount > 0)
- {
- // Edge -> Edge
- var broadEdgeEdgeJob = new EdgeEdgeBroadPhaseJob()
- {
- teamDataArray = tm.teamDataArray.GetNativeArray(),
-
- primitiveArray = primitiveArray.GetNativeArray(),
- sortAndSweepArray = sortAndSweepArray.GetNativeArray(),
-
- processingEdgeEdgeArray = sm.processingSelfEdgeEdge.Buffer,
-
- edgeEdgeContactQueue = edgeEdgeContactQueue.AsParallelWriter(),
-
- intersectFlagArray = intersectFlagArray,
- };
- jobHandle = broadEdgeEdgeJob.Schedule(sm.processingSelfEdgeEdge.GetJobSchedulePtr(), 16, jobHandle);
- }
-
- // PointTriangle
- if (PointPrimitiveCount > 0)
- {
- // Point -> Triangle
- var broadPointTriangleJob = new PointTriangleBroadPhaseJob()
- {
- mainKind = KindPoint,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
-
- triangles = vm.triangles.GetNativeArray(),
- attributes = vm.attributes.GetNativeArray(),
-
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- oldPosArray = sm.oldPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
-
- primitiveArray = primitiveArray.GetNativeArray(),
- sortAndSweepArray = sortAndSweepArray.GetNativeArray(),
-
- processingPointTriangleArray = sm.processingSelfPointTriangle.Buffer,
-
- pointTriangleContactQueue = pointTriangleContactQueue.AsParallelWriter(),
-
- intersectFlagArray = intersectFlagArray,
- };
- jobHandle = broadPointTriangleJob.Schedule(sm.processingSelfPointTriangle.GetJobSchedulePtr(), 16, jobHandle);
- }
- if (TrianglePrimitiveCount > 0)
- {
- // Triangle -> Point
- var broadTrianglePointJob = new PointTriangleBroadPhaseJob()
- {
- mainKind = KindTriangle,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
-
- triangles = vm.triangles.GetNativeArray(),
- attributes = vm.attributes.GetNativeArray(),
-
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- oldPosArray = sm.oldPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
-
- primitiveArray = primitiveArray.GetNativeArray(),
- sortAndSweepArray = sortAndSweepArray.GetNativeArray(),
-
- processingPointTriangleArray = sm.processingSelfTrianglePoint.Buffer,
-
- pointTriangleContactQueue = pointTriangleContactQueue.AsParallelWriter(),
-
- intersectFlagArray = intersectFlagArray,
- };
- jobHandle = broadTrianglePointJob.Schedule(sm.processingSelfTrianglePoint.GetJobSchedulePtr(), 16, jobHandle);
- }
-
- // ToList
- var toListJob1 = new EdgeEdgeToListJob()
- {
- edgeEdgeContactQueue = edgeEdgeContactQueue,
- edgeEdgeContactList = edgeEdgeContactList,
- }.Schedule(jobHandle);
- var toListJob2 = new PointTriangleToListJob()
- {
- pointTriangleContactQueue = pointTriangleContactQueue,
- pointTriangleContactList = pointTriangleContactList,
- }.Schedule(jobHandle);
- jobHandle = JobHandle.CombineDependencies(toListJob1, toListJob2);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct ClearBufferJob : IJob
- {
- [Unity.Collections.WriteOnly]
- public NativeQueue edgeEdgeContactQueue;
-
- [Unity.Collections.WriteOnly]
- public NativeQueue pointTriangleContactQueue;
-
- public void Execute()
- {
- edgeEdgeContactQueue.Clear();
- pointTriangleContactQueue.Clear();
- }
- }
-
-#if false
- [BurstCompile]
- struct SetupContactGroupJob : IJob
- {
- public int teamCount;
- public int useQueueCount;
-
- // team
- public NativeArray teamDataArray;
-
- public void Execute()
- {
- // まずセルフコリジョンが有効で同期していないチームのグループインデックスを決定する
- int groupIndex = 0;
- var restTeam = new NativeList(teamCount, Allocator.Temp);
- for (int i = 1; i < teamCount; i++)
- {
- var tdata = teamDataArray[i];
- if (tdata.IsValid == false || tdata.IsEnable == false || tdata.IsStepRunning == false)
- continue;
- if (tdata.flag.TestAny(TeamManager.Flag_Self_PointPrimitive, 3) == false)
- continue;
-
- // このチームはセルフコリジョンを実行する
- if (tdata.flag.IsSet(TeamManager.Flag_Synchronization))
- {
- // 同期
- // 後で解決する
- restTeam.Add(i);
- }
- else
- {
- // コンタクトグループを割り振る
- tdata.selfQueueIndex = groupIndex % useQueueCount;
- //Debug.Log($"tid:{i} Main selfQueueIndex:{tdata.selfQueueIndex}");
- teamDataArray[i] = tdata;
- groupIndex++;
- }
- }
-
- // 同期チームは同期先のグループIDを指す
- if (restTeam.Length > 0)
- {
- foreach (var teamId in restTeam)
- {
- var tdata = teamDataArray[teamId];
- var stdata = teamDataArray[tdata.syncTeamId];
- while (stdata.syncTeamId != 0)
- {
- stdata = teamDataArray[stdata.syncTeamId];
- }
- tdata.selfQueueIndex = stdata.selfQueueIndex;
- teamDataArray[teamId] = tdata;
- //Debug.Log($"tid:{teamId} Sync selfQueueIndex:{tdata.selfQueueIndex}");
- }
- }
- }
- }
-#endif
-
- [BurstCompile]
- struct UpdatePrimitiveJob : IJobParallelForDefer
- {
- // プリミティブ種類
- public uint kind;
-
- // team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
-
- // vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray depthArray;
-
- // particle
- [Unity.Collections.ReadOnly]
- public NativeArray nextPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray oldPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray frictionArray;
- //[Unity.Collections.ReadOnly]
- //public NativeArray stepBasicPositionBuffer;
-
- // constraint
- [NativeDisableParallelForRestriction]
- public NativeArray primitiveArray;
- [NativeDisableParallelForRestriction]
- public NativeArray sortAndSweepArray;
-
- // processing
- [Unity.Collections.ReadOnly]
- public NativeArray processingArray;
-
- // プリミティブごと
- public void Execute(int index)
- {
- uint pack = processingArray[index];
- int teamId = DataUtility.Unpack32Hi(pack);
- int l_index = DataUtility.Unpack32Low(pack);
-
- // チームはこのステップで有効であることが保証されている
- var tdata = teamDataArray[teamId];
- int pstart = tdata.particleChunk.startIndex;
-
- var param = parameterArray[teamId].selfCollisionConstraint;
-
- // primitive
- int pri_index = 0;
- switch (kind)
- {
- case KindPoint:
- pri_index = tdata.selfPointChunk.startIndex + l_index;
- break;
- case KindEdge:
- pri_index = tdata.selfEdgeChunk.startIndex + l_index;
- break;
- case KindTriangle:
- pri_index = tdata.selfTriangleChunk.startIndex + l_index;
- break;
- }
- var primitive = primitiveArray[pri_index];
- uint flag = primitive.flagAndTeamId;
-
- // プリミティブ更新
- int ac = (int)kind + 1; // 軸の数
+ // フラグなど
+ uint flag = 0;
uint fix_flag = Flag_Fix0;
bool ignore = false;
int fixcnt = 0;
float depth = 0;
+ int ac = (int)kind + 1; // 軸の数
for (int i = 0; i < ac; i++)
{
- int pindex = primitive.particleIndices[i];
- primitive.nextPos[i] = nextPosArray[pindex];
- primitive.oldPos[i] = oldPosArray[pindex];
- //primitive.basePos[i] = stepBasicPositionBuffer[pindex];
+ int pindex = particleIndices[i];
int vindex = tdata.proxyCommonChunk.startIndex + pindex - pstart;
var attr = attributes[vindex];
if (attr.IsMove())
@@ -1255,8 +739,7 @@ namespace MagicaCloth2
fix_flag <<= 1;
if (attr.IsInvalid())
ignore = true;
- primitive.invMass[i] = MathUtility.CalcSelfCollisionInverseMass(frictionArray[pindex], attr.IsDontMove(), param.clothMass);
- depth += depthArray[vindex];
+ depth += vertexDepths[vindex];
}
if (fixcnt == ac)
flag |= Flag_AllFix;
@@ -1264,110 +747,49 @@ namespace MagicaCloth2
flag &= ~Flag_AllFix;
if (ignore)
flag |= Flag_Ignore;
- primitive.flagAndTeamId = flag;
depth /= ac;
- //float thickness = parameterArray[teamId].selfCollisionConstraint.surfaceThicknessCurveData.EvaluateCurve(depth);
- float thickness = param.surfaceThicknessCurveData.EvaluateCurve(depth);
- thickness *= tdata.scaleRatio; // team scale
- primitive.thickness = thickness;
- primitiveArray[pri_index] = primitive;
- // AABB
- var aabb = new AABB(math.min(primitive.nextPos[0], primitive.oldPos[0]), math.max(primitive.nextPos[0], primitive.oldPos[0]));
- for (int i = 1; i < ac; i++)
- {
- aabb.Encapsulate(primitive.nextPos[i]);
- aabb.Encapsulate(primitive.oldPos[i]);
- }
- aabb.Expand(thickness); // 厚み
- //aabb.Expand(0.03f); // 厚み
+ p.flag = (kind << 24) | flag;
+ p.particleIndices = particleIndices;
+ p.depth = depth;
+ p.grid = Define.System.SelfCollisionIgnoreGrid; // 無効グリッド
- // update sort
- int sortIndex = primitive.sortIndex;
- var sd = sortAndSweepArray[sortIndex];
- sd.flagAndTeamId = primitive.flagAndTeamId;
- sd.firstMinMax = new float2(aabb.Min.y, aabb.Max.y);
- sd.secondMinMax = new float2(aabb.Min.x, aabb.Max.x);
- sd.thirdMinMax = new float2(aabb.Min.z, aabb.Max.z);
- sortAndSweepArray[sortIndex] = sd;
- //Debug.Log($"Update Primitive[{pri_index}] pindices:{primitive.particleIndices}, flag:0x{primitive.flagAndTeamId >> 24:X}");
+ primitiveArrayB[pri_index] = p;
+
+ //Debug.Log($"pri[{pri_index}] p:{p.particleIndices}, {p.GetKind()}");
}
}
- [BurstCompile]
- unsafe struct SortJob : IJobParallelFor
+ ///
+ /// 作業バッファ更新
+ ///
+ internal void WorkBufferUpdate()
{
- // team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
-
- // constraint
- [NativeDisableParallelForRestriction]
- public NativeArray primitiveArray;
- [NativeDisableParallelForRestriction]
- public NativeArray sortAndSweepArray;
-
- // チームごと(Point/Edge/Triangle)
- public void Execute(int index)
+ // 交差フラグバッファ
+ if (IntersectCount > 0)
{
- int teamId = index / 3;
- int type = index % 3; // 0=Point, 1=Edge, 2=Triangle
-
- if (teamId == 0)
- return;
-
- var tdata = teamDataArray[teamId];
- if (tdata.IsProcess == false)
- return;
-
- DataChunk sortChunk = default(DataChunk);
- switch (type)
- {
- case 0:
- sortChunk = tdata.selfPointChunk;
- break;
- case 1:
- sortChunk = tdata.selfEdgeChunk;
- break;
- case 2:
- sortChunk = tdata.selfTriangleChunk;
- break;
- }
- if (sortChunk.IsValid == false)
- return;
-
- // 書き込みポインタ
- SortData* pt = (SortData*)sortAndSweepArray.GetUnsafePtr();
- pt += sortChunk.startIndex;
- NativeSortExtension.Sort(pt, sortChunk.dataLength);
-
- // ソート後のインデックスをプリミティブに書き戻す
- for (int i = 0; i < sortChunk.dataLength; i++)
- {
- int sortIndex = sortChunk.startIndex + i;
- var sd = sortAndSweepArray[sortIndex];
- var primitive = primitiveArray[sd.primitiveIndex];
- primitive.sortIndex = sortIndex;
- primitiveArray[sd.primitiveIndex] = primitive;
- //Debug.Log($"sort[{i}] primitive:{sd.primitiveIndex}, prisortidx:{primitive.sortIndex}, first:{sd.firstMinMax}, second:{sd.secondMinMax}, third:{sd.thirdMinMax}");
- }
+ int pcnt = MagicaManager.Simulation.ParticleCount;
+ intersectFlagArray.MC2Resize(pcnt, options: NativeArrayOptions.ClearMemory);
}
}
+ //=========================================================================================
+ // Primitive
+ //=========================================================================================
[BurstCompile]
- struct PointTriangleBroadPhaseJob : IJobParallelForDefer
+ unsafe internal struct SelfStep_UpdatePrimitiveJob : IJobParallelFor
{
- public uint mainKind;
+ public int workerCount;
+ public int updateIndex;
+ public float4 simulationPower;
// team
[Unity.Collections.ReadOnly]
+ public NativeList batchSelfTeamList;
+ [Unity.Collections.ReadOnly]
public NativeArray teamDataArray;
-
- // vmesh
[Unity.Collections.ReadOnly]
- public NativeArray triangles;
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
+ public NativeArray parameterArray;
// particle
[Unity.Collections.ReadOnly]
@@ -1377,536 +799,755 @@ namespace MagicaCloth2
[Unity.Collections.ReadOnly]
public NativeArray frictionArray;
- // constraint
- [Unity.Collections.ReadOnly]
- public NativeArray primitiveArray;
- [Unity.Collections.ReadOnly]
- public NativeArray sortAndSweepArray;
-
- // processing
- [Unity.Collections.ReadOnly]
- public NativeArray processingPointTriangleArray;
-
- // contact buffer
- [Unity.Collections.WriteOnly]
- public NativeQueue.ParallelWriter pointTriangleContactQueue;
-
+ // self collision
+ public bool useIntersect;
+ [NativeDisableParallelForRestriction]
+ public NativeArray primitiveArrayB;
[Unity.Collections.ReadOnly]
public NativeArray intersectFlagArray;
- // 解決PointTriangleごと
+ // バッチ内のローカルチームインデックスごと
+ // ワーカー分割(3固定)
public void Execute(int index)
{
- uint pack = processingPointTriangleArray[index];
- int teamId = DataUtility.Unpack32Hi(pack);
- int l_index = DataUtility.Unpack32Low(pack);
+ // チームIDとワーカーID
+ int localIndex = index / workerCount;
+ int workerIndex = index % workerCount;
- // チームはこのステップで有効であることが保証されている
- var tdata = teamDataArray[teamId];
+ // 各ベースポインタ
+ TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr();
+ ClothParameters* paramPt = (ClothParameters*)parameterArray.GetUnsafeReadOnlyPtr();
- // メインとサブのチャンク
- bool isPoint = mainKind == KindPoint;
- var mainChunk = isPoint ? tdata.selfPointChunk : tdata.selfTriangleChunk;
- var subChunk = isPoint ? tdata.selfTriangleChunk : tdata.selfPointChunk;
+ int teamId = batchSelfTeamList[localIndex];
+ ref var tdata = ref *(teamPt + teamId);
+ ref var param = ref *(paramPt + teamId);
- // Main Primitive
- int pri_index = mainChunk.startIndex + l_index;
- var primitive0 = primitiveArray[pri_index];
- var sd0 = sortAndSweepArray[primitive0.sortIndex];
-
- // 無効判定
- if (primitive0.IsIgnore())
+ if (updateIndex >= tdata.updateCount)
+ return;
+ if (tdata.IsProcess == false)
+ return;
+ if (tdata.ParticleCount == 0)
return;
- // 交差中ならば無効
- if (tdata.flag.TestAny(TeamManager.Flag_Self_EdgeTriangleIntersect, 6))
+ // セルフコリジョン
+ // ■プリミティブとグリッドの更新
+ // 範囲
+ //var chunk = MathUtility.GetWorkerChunk(tdata.particleChunk.dataLength, workerCount, workerIndex);
+ //if (chunk.IsValid)
{
- int ac = isPoint ? 1 : 3;
- for (int i = 0; i < ac; i++)
- {
- if (intersectFlagArray[primitive0.particleIndices[i]] > 0)
- return;
- }
- }
-
- //=============================================================
- // Self
- //=============================================================
- if (tdata.flag.IsSet(isPoint ? TeamManager.Flag_Self_PointTriangle : TeamManager.Flag_Self_TrianglePoint))
- {
- SweepTest(-1, ref primitive0, sd0, subChunk, true);
- }
-
- //=============================================================
- // Sync
- //=============================================================
- if (tdata.flag.IsSet(isPoint ? TeamManager.Flag_Sync_PointTriangle : TeamManager.Flag_Sync_TrianglePoint) && tdata.syncTeamId > 0)
- {
- var stdata = teamDataArray[tdata.syncTeamId];
- SweepTest(-1, ref primitive0, sd0, isPoint ? stdata.selfTriangleChunk : stdata.selfPointChunk, false);
- }
-
- //=============================================================
- // Parent Sync
- //=============================================================
- if (tdata.flag.IsSet(isPoint ? TeamManager.Flag_PSync_PointTriangle : TeamManager.Flag_PSync_TrianglePoint))
- {
- int cnt = tdata.syncParentTeamId.Length;
- for (int j = 0; j < cnt; j++)
- {
- int parentTeamId = tdata.syncParentTeamId[j];
- var stdata = teamDataArray[parentTeamId];
- if (stdata.flag.IsSet(isPoint ? TeamManager.Flag_Sync_TrianglePoint : TeamManager.Flag_Sync_PointTriangle))
- {
- SweepTest(-1, ref primitive0, sd0, isPoint ? stdata.selfTriangleChunk : stdata.selfPointChunk, false);
- }
- }
- }
- }
-
- void SweepTest(int sortIndex, ref Primitive primitive0, in SortData sd0, in DataChunk subChunk, bool connectionCheck)
- {
- Debug.Assert(subChunk.IsValid);
-
- // スイープ
- if (sortIndex < 0)
- sortIndex = BinarySearchSortAndlSweep(ref sortAndSweepArray, sd0, subChunk);
-
- float end = sd0.firstMinMax.y;
- int endIndex = subChunk.startIndex + subChunk.dataLength;
- while (sortIndex < endIndex)
- {
- var sd1 = sortAndSweepArray[sortIndex];
- sortIndex++;
-
- // first
- if (sd1.firstMinMax.x <= end)
- {
- // second
- if (sd1.secondMinMax.y < sd0.secondMinMax.x || sd1.secondMinMax.x > sd0.secondMinMax.y)
- continue;
-
- // third
- if (sd1.thirdMinMax.y < sd0.thirdMinMax.x || sd1.thirdMinMax.x > sd0.thirdMinMax.y)
- continue;
-
- // この時点で両方のAABBは衝突している
- var primitive1 = primitiveArray[sd1.primitiveIndex];
-
- // 無効判定
- if (primitive1.IsIgnore())
- continue;
-
- // プリミティブ同士が接続している場合は無効
- if (connectionCheck && primitive0.AnyParticle(primitive1))
- continue;
-
- // 両方のプリミティブが完全固定ならば無効
- if ((primitive0.flagAndTeamId & Flag_AllFix) != 0 && (primitive1.flagAndTeamId & Flag_AllFix) != 0)
- continue;
-
- // 交差判定
- // 厚みとSCR
- float solveThickness = primitive0.GetSolveThickness(primitive1);
- float scr = solveThickness * Define.System.SelfCollisionSCR;
- if (solveThickness < 0.0001f)
- continue;
-
- // 接触予測判定
- if (mainKind == KindPoint)
- BroadPointTriangle(ref primitive0, ref primitive1, solveThickness, scr, Define.System.SelfCollisionPointTriangleAngleCos);
- else
- BroadPointTriangle(ref primitive1, ref primitive0, solveThickness, scr, Define.System.SelfCollisionPointTriangleAngleCos);
- }
- else
- break;
- }
- }
-
- void BroadPointTriangle(ref Primitive p_pri, ref Primitive t_pri, float thickness, float scr, float ang)
- {
- // 変位
- var dA = p_pri.nextPos.c0 - p_pri.oldPos.c0;
- var dB0 = t_pri.nextPos.c0 - t_pri.oldPos.c0;
- var dB1 = t_pri.nextPos.c1 - t_pri.oldPos.c1;
- var dB2 = t_pri.nextPos.c2 - t_pri.oldPos.c2;
-
- //=========================================================
- // 衝突予測と格納
- //=========================================================
- float3 uvw, cp;
- // 移動前ポイントと移動前トライアングルへの最近接点
- cp = MathUtility.ClosestPtPointTriangle(p_pri.oldPos.c0, t_pri.oldPos.c0, t_pri.oldPos.c1, t_pri.oldPos.c2, out uvw);
-
- // 最近接点座標の変位を求める
- float3 dt = dB0 * uvw.x + dB1 * uvw.y + dB2 * uvw.z;
-
- // 最近接点ベクトル
- float3 cv = cp - p_pri.oldPos.c0;
- float cvlen = math.length(cv);
- if (cvlen > Define.System.Epsilon)
- {
- var n = cv / cvlen;
-
- // 変位dp,dtをnに投影して距離チェック
- float l0 = math.dot(n, dA);
- float l1 = math.dot(n, dt);
- float l = cvlen - l0 + l1;
-
- // ダイナミックThicknessテスト
-#if false
- if (p_pri.GetTeamId() == t_pri.GetTeamId())
- {
- var bcp = MathUtility.ClosestPtPointTriangle(p_pri.basePos.c0, t_pri.basePos.c0, t_pri.basePos.c1, t_pri.basePos.c2, out _);
- float blen = math.distance(p_pri.basePos.c0, bcp);
- //blen *= 0.7f;
- if (blen < 0.005f)
- return;
- //if (thickness > blen)
- // Debug.Log($"PT thickness:{thickness}, blen:{blen}");
- thickness = math.min(thickness, blen);
- scr = thickness * Define.System.SelfCollisionSCR;
- }
-#endif
-
- // 接続判定
- if (l < (thickness + scr))
- {
- //=========================================================
- // 方向性判定
- //=========================================================
- float sign = 0;
- // 移動前トライアングル法線
- float3 otn = MathUtility.TriangleNormal(t_pri.oldPos.c0, t_pri.oldPos.c1, t_pri.oldPos.c2);
-
- // 移動前のパーティクル方向性
- n = math.normalize(p_pri.oldPos.c0 - cp);
- float dot = math.dot(otn, n);
-
- // 移動前にトライアングル面に対してほぼ水平ならば無視する
- if (math.abs(dot) >= ang)
- sign = math.sign(dot);
- else
- return;
-
- //=========================================================
- // 接触情報作成
- //=========================================================
- var contact = new PointTriangleContact();
- contact.flagAndTeamId0 = p_pri.flagAndTeamId | Flag_Enable;
- contact.flagAndTeamId1 = t_pri.flagAndTeamId;
- contact.thickness = (half)thickness;
- contact.sign = (half)sign;
- contact.pointParticleIndex = p_pri.particleIndices.x;
- contact.triangleParticleIndex = t_pri.particleIndices;
- contact.pointInvMass = (half)p_pri.invMass.x;
- contact.triangleInvMass = (half3)t_pri.invMass;
- //Debug.Log(contact.ToString());
-
- pointTriangleContactQueue.Enqueue(contact);
- }
+ UpdatePrimitive(
+ workerIndex,
+ // team
+ teamId,
+ ref tdata,
+ ref param,
+ // particle
+ ref nextPosArray,
+ ref oldPosArray,
+ ref frictionArray,
+ // self collisiotn
+ useIntersect,
+ ref primitiveArrayB,
+ ref intersectFlagArray
+ );
}
}
}
- [BurstCompile]
- struct EdgeEdgeBroadPhaseJob : IJobParallelForDefer
- {
+ ///
+ /// ブロードフェーズ
+ /// プリミティブ更新
+ ///
+ unsafe static void UpdatePrimitive(
+ int k,
// team
+ int teamId,
+ ref TeamManager.TeamData tdata,
+ ref ClothParameters param,
+ // particle
+ ref NativeArray nextPosArray,
+ ref NativeArray oldPosArray,
+ ref NativeArray frictionArray,
+ // self collision
+ bool useIntersect,
+ ref NativeArray primitiveArrayB,
+ ref NativeArray intersectFlagArray
+ )
+ {
+ // チームの種類ごと(0:Point,1:Edge,2:Triangle)
+
+ // ■プリミティブ更新 ===================================================================
+ Primitive* pt = (Primitive*)primitiveArrayB.GetUnsafePtr();
+
+ int pstart = tdata.particleChunk.startIndex;
+
+ // (0)Point/(1)Edge/(2)Triangle
+ float maxPrimitiveSize = 0;
+ //for (int k = 0; k < 3; k++)
+ {
+ DataChunk pc = k == KindPoint ? tdata.selfPointChunk : (k == KindEdge ? tdata.selfEdgeChunk : tdata.selfTriangleChunk);
+ //Debug.Log($"[{teamId}] kind:{k} pc:{pc.ToString()}");
+
+ if (pc.IsValid)
+ {
+ uint kind = (uint)k;
+
+ float3x3 nextPos = 0;
+ float3x3 oldPos = 0;
+
+ int priIndex = pc.startIndex;
+ for (int j = 0; j < pc.dataLength; j++, priIndex++)
+ {
+ ref var p = ref *(pt + priIndex);
+
+ if (p.IsIgnore())
+ continue;
+
+ // プリミティブ更新
+ int ac = k + 1; // 軸の数
+ uint fix_flag = Flag_Fix0;
+ uint intersect_flag = 0;
+ for (int i = 0; i < ac; i++)
+ {
+ int pindex = p.particleIndices[i];
+ nextPos[i] = nextPosArray[pindex];
+ oldPos[i] = oldPosArray[pindex];
+ bool fix = (p.flag & fix_flag) != 0;
+ p.invMass[i] = MathUtility.CalcSelfCollisionInverseMass(frictionArray[pindex], fix, param.selfCollisionConstraint.clothMass);
+ fix_flag <<= 1;
+
+ if (useIntersect && intersectFlagArray[pindex] != 0)
+ intersect_flag |= (Flag_Intersect0 << i);
+ }
+ float thickness = param.selfCollisionConstraint.surfaceThicknessCurveData.MC2EvaluateCurve(p.depth);
+ thickness *= tdata.scaleRatio; // team scale
+ p.thickness = thickness;
+
+ // プリミティブAABB
+ var aabb = new AABB(math.min(nextPos[0], oldPos[0]), math.max(nextPos[0], oldPos[0]));
+ for (int i = 1; i < ac; i++)
+ {
+ aabb.Encapsulate(nextPos[i]);
+ aabb.Encapsulate(oldPos[i]);
+ }
+ float aabbSize = aabb.MaxSideLength;
+ maxPrimitiveSize = math.max(maxPrimitiveSize, aabbSize);
+ aabb.Expand(thickness); // 厚み
+ p.aabb = aabb;
+
+ // インターセクトフラグ更新
+ p.flag = (p.flag & 0xfffffff8) | intersect_flag;
+ }
+ }
+ }
+
+ // ■UniformGridサイズ決定 ==============================================================
+ // 種類がEdgeの場合のみ設定
+ if (k == KindEdge)
+ {
+ const float uniformGridScale = 3.0f; // 一旦これで 3.0?
+ float gridSize = maxPrimitiveSize * uniformGridScale;
+ tdata.selfGridSize = gridSize;
+ tdata.selfMaxPrimitiveSize = maxPrimitiveSize; // 最大プリミティブサイズ
+ //Debug.Log($"[{teamId}] maxPrimitiveSize:{maxPrimitiveSize} gridSize:{gridSize}");
+ }
+ //Debug.Log($"[{teamId}] kind:{k}, maxPrimitiveSize:{maxPrimitiveSize}");
+ }
+
+ [BurstCompile]
+ unsafe internal struct SelfStep_UpdateGridJob : IJobParallelFor
+ {
+ public int kindCount;
+ public int updateIndex;
+ public float4 simulationPower;
+
+ // team
+ [Unity.Collections.ReadOnly]
+ public NativeList batchSelfTeamList;
[Unity.Collections.ReadOnly]
public NativeArray teamDataArray;
- // constraint
+ // self collision
[Unity.Collections.ReadOnly]
- public NativeArray primitiveArray;
- [Unity.Collections.ReadOnly]
- public NativeArray sortAndSweepArray;
+ public NativeArray primitiveArrayB;
+ [NativeDisableParallelForRestriction]
+ [NativeDisableContainerSafetyRestriction]
+ public NativeArray uniformGridStartCountBuffer;
- // processing
- [Unity.Collections.ReadOnly]
- public NativeArray processingEdgeEdgeArray;
-
- // contact buffer
- [Unity.Collections.WriteOnly]
- public NativeQueue.ParallelWriter edgeEdgeContactQueue;
-
- [Unity.Collections.ReadOnly]
- public NativeArray intersectFlagArray;
-
- // 解決エッジごと
+ // バッチ内のローカルチームインデックスごと
+ // ワーカー分割(3固定)
public void Execute(int index)
{
- uint pack = processingEdgeEdgeArray[index];
- int teamId = DataUtility.Unpack32Hi(pack);
- int l_index = DataUtility.Unpack32Low(pack);
+ // チームIDとワーカーID
+ int localIndex = index / kindCount;
+ int kindIndex = index % kindCount;
- // チームはこのステップで有効であることが保証されている
- var tdata = teamDataArray[teamId];
+ // 各ベースポインタ
+ TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr();
- int pri_index = tdata.selfEdgeChunk.startIndex + l_index;
- var primitive0 = primitiveArray[pri_index];
+ int teamId = batchSelfTeamList[localIndex];
+ ref var tdata = ref *(teamPt + teamId);
- // 無効
- if (primitive0.IsIgnore())
+ if (updateIndex >= tdata.updateCount)
+ return;
+ if (tdata.IsProcess == false)
+ return;
+ if (tdata.ParticleCount == 0)
return;
- // 交差中ならば無効
- if (tdata.flag.TestAny(TeamManager.Flag_Self_EdgeTriangleIntersect, 6))
+ // セルフコリジョン
+ // ■プリミティブとグリッドの更新(初回ステップのみ)
+ if (updateIndex == 0)
{
- if (intersectFlagArray[primitive0.particleIndices.x] > 0)
- return;
- if (intersectFlagArray[primitive0.particleIndices.y] > 0)
- return;
+ UpdateGrid(
+ kindIndex,
+ // team
+ teamId,
+ ref tdata,
+ // self collisiotn
+ ref primitiveArrayB,
+ ref uniformGridStartCountBuffer
+ );
}
+ }
+ }
- // sort
- var sd0 = sortAndSweepArray[primitive0.sortIndex];
+ unsafe static void UpdateGrid(
+ int k,
+ // team
+ int teamId,
+ ref TeamManager.TeamData tdata,
+ // self collision
+ ref NativeArray primitiveArrayB,
+ ref NativeArray uniformGridStartCountBuffer
+ )
+ {
+ // チームの種類ごと(0:Point,1:Edge,2:Triangle)
- //=============================================================
- // Self
- //=============================================================
- if (tdata.flag.IsSet(TeamManager.Flag_Self_EdgeEdge))
+ // ■プリミティブ更新 ===================================================================
+ Primitive* pt = (Primitive*)primitiveArrayB.GetUnsafeReadOnlyPtr();
+ GridInfo* gt = (GridInfo*)uniformGridStartCountBuffer.GetUnsafePtr();
+
+ //int pstart = tdata.particleChunk.startIndex;
+
+ // ■ここからは自身のグリッドが参照される場合のみで良い
+ // つまり自身のセルフコリジョンか親からの相互コリジョン
+ if (tdata.flag.IsSet(TeamManager.Flag_Self_EdgeEdge)
+ || tdata.flag.IsSet(TeamManager.Flag_Self_PointTriangle)
+ || tdata.flag.IsSet(TeamManager.Flag_Self_TrianglePoint)
+ || tdata.flag.IsSet(TeamManager.Flag_PSync_EdgeEdge)
+ || tdata.flag.IsSet(TeamManager.Flag_PSync_PointTriangle)
+ || tdata.flag.IsSet(TeamManager.Flag_PSync_TrianglePoint)
+ )
+ {
{
- SweepTest(primitive0.sortIndex + 1, ref primitive0, sd0, tdata.selfEdgeChunk, true);
- }
-
- //=============================================================
- // Sync
- //=============================================================
- if (tdata.flag.IsSet(TeamManager.Flag_Sync_EdgeEdge) && tdata.syncTeamId > 0)
- {
- var stdata = teamDataArray[tdata.syncTeamId];
- SweepTest(-1, ref primitive0, sd0, stdata.selfEdgeChunk, false);
- }
-
- //=============================================================
- // Parent Sync
- //=============================================================
- if (tdata.flag.IsSet(TeamManager.Flag_PSync_EdgeEdge))
- {
- int cnt = tdata.syncParentTeamId.Length;
- for (int j = 0; j < cnt; j++)
+ DataChunk pc = k == KindPoint ? tdata.selfPointChunk : (k == KindEdge ? tdata.selfEdgeChunk : tdata.selfTriangleChunk);
+ //Debug.Log($"[{teamId}] calc grid. kind:{k} pstart:{pc.startIndex}, pcount:{pc.dataLength}");
+ if (pc.IsValid)
{
- int parentTeamId = tdata.syncParentTeamId[j];
- var stdata = teamDataArray[parentTeamId];
- if (stdata.flag.IsSet(TeamManager.Flag_Sync_EdgeEdge))
+ // ■プリミティブのグリッド座標算出 =======================================================
+ int priIndex = pc.startIndex;
+ for (int j = 0; j < pc.dataLength; j++, priIndex++)
{
- SweepTest(-1, ref primitive0, sd0, stdata.selfEdgeChunk, false);
+ ref var p = ref *(pt + priIndex);
+ if (p.IsIgnore())
+ p.grid = Define.System.SelfCollisionIgnoreGrid; // 無効グリッド
+ else
+ p.grid = GetGrid(p.aabb.Center, tdata.selfGridSize);
}
+
+ // ■プリミティブをグリッド順にソートする =================================================
+ NativeSortExtension.Sort(pt + pc.startIndex, pc.dataLength);
+
+ // ■グリッドの開始位置と数を摘出する =====================================================
+ int3 nowGrid = 0;
+ int nowGridStart = 0;
+ int nowGridCount = 0;
+ int gridBufferStart = pc.startIndex;
+ int gridBufferIndex = gridBufferStart;
+ int gridBufferCount = 0;
+ priIndex = pc.startIndex;
+ for (int i = 0; i < pc.dataLength; i++, priIndex++)
+ {
+ ref var p = ref *(pt + priIndex);
+
+ if (i == 0)
+ {
+ // 初回グリッド
+ nowGrid = p.grid;
+ nowGridStart = priIndex;
+ nowGridCount = 0;
+ }
+ else if (p.grid.Equals(nowGrid.xyz) == false)
+ {
+ // 現在のグリッドを保存
+ uniformGridStartCountBuffer[gridBufferIndex] = new GridInfo() { hash = nowGrid.GetHashCode(), start = nowGridStart, count = nowGridCount };
+ gridBufferIndex++;
+ gridBufferCount++;
+ //Debug.Log(nowGrid.GetHashCode());
+
+ // 次のグリッドの開始
+ nowGrid = p.grid;
+ nowGridStart = priIndex;
+ nowGridCount = 0;
+ }
+ nowGridCount++;
+ }
+ // 最後のグリッドを記録
+ if (nowGridCount > 0)
+ {
+ uniformGridStartCountBuffer[gridBufferIndex] = new GridInfo() { hash = nowGrid.GetHashCode(), start = nowGridStart, count = nowGridCount };
+ gridBufferIndex++;
+ gridBufferCount++;
+ //Debug.Log(nowGrid.GetHashCode());
+ }
+
+ // グリッド数を記録
+ switch (k)
+ {
+ case 0:
+ tdata.selfPointGridCount = gridBufferCount;
+ break;
+ case 1:
+ tdata.selfEdgeGridCount = gridBufferCount;
+ break;
+ case 2:
+ tdata.selfTriangleGridCount = gridBufferCount;
+ break;
+ }
+
+ // グリッド情報をハッシュでソート
+ // 2分探索のため
+ NativeSortExtension.Sort(gt + gridBufferStart, gridBufferCount);
+
+ //Debug.Log($"[{teamId}] calc grid. kind:{k} pstart:{pc.startIndex}, pcount:{pc.dataLength}, grid count:{gridBufferCount}");
}
}
}
-
- void SweepTest(int sortIndex, ref Primitive primitive0, in SortData sd0, in DataChunk subChunk, bool connectionCheck)
- {
- // スイープ
- if (sortIndex < 0)
- sortIndex = BinarySearchSortAndlSweep(ref sortAndSweepArray, sd0, subChunk);
- float end = sd0.firstMinMax.y;
- int endIndex = subChunk.startIndex + subChunk.dataLength;
- while (sortIndex < endIndex)
- {
- var sd1 = sortAndSweepArray[sortIndex];
- sortIndex++;
-
- // first
- if (sd1.firstMinMax.x <= end)
- {
- // second
- if (sd1.secondMinMax.y < sd0.secondMinMax.x || sd1.secondMinMax.x > sd0.secondMinMax.y)
- continue;
-
- // third
- if (sd1.thirdMinMax.y < sd0.thirdMinMax.x || sd1.thirdMinMax.x > sd0.thirdMinMax.y)
- continue;
-
- // この時点で両方のAABBは衝突している
- var primitive1 = primitiveArray[sd1.primitiveIndex];
-
- // 無効判定
- if (primitive1.IsIgnore())
- continue;
-
- // プリミティブ同士が接続している場合は無効
- if (connectionCheck && primitive0.AnyParticle(primitive1))
- continue;
-
- // 両方のプリミティブが完全固定ならば無効
- if ((primitive0.flagAndTeamId & Flag_AllFix) != 0 && (primitive1.flagAndTeamId & Flag_AllFix) != 0)
- continue;
-
- // 交差判定
- // 厚みとSCR
- float solveThickness = primitive0.GetSolveThickness(primitive1);
- float scr = solveThickness * Define.System.SelfCollisionSCR;
- if (solveThickness < 0.0001f)
- continue;
-
- // 接触予測判定
- BroadEdgeEdge(ref primitive0, ref primitive1, solveThickness, scr);
- }
- else
- break;
- }
- }
-
- void BroadEdgeEdge(ref Primitive pri0, ref Primitive pri1, float thickness, float scr)
- {
- // 移動前の2つの線分の最近接点
- float s, t;
- float3 cA, cB;
- float csqlen = MathUtility.ClosestPtSegmentSegment(pri0.oldPos[0], pri0.oldPos[1], pri1.oldPos[0], pri1.oldPos[1], out s, out t, out cA, out cB);
- float clen = math.sqrt(csqlen); // 最近接点の距離
- if (clen < 1e-09f)
- return;
-
- // 押出法線
- float3 n = (cA - cB) / clen;
-
- // 最近接点での変位
- var dA0 = pri0.nextPos[0] - pri0.oldPos[0];
- var dA1 = pri0.nextPos[1] - pri0.oldPos[1];
- var dB0 = pri1.nextPos[0] - pri1.oldPos[0];
- var dB1 = pri1.nextPos[1] - pri1.oldPos[1];
- float3 da = math.lerp(dA0, dA1, s);
- float3 db = math.lerp(dB0, dB1, t);
-
- // 変位da,dbをnに投影して距離チェック
- float l0 = math.dot(n, da);
- float l1 = math.dot(n, db);
- float l = clen + l0 - l1;
-
- // ダイナミックThicknessテスト
-#if false
- if (pri0.GetTeamId() == pri1.GetTeamId())
- {
- float bsqlen = MathUtility.ClosestPtSegmentSegment(pri0.basePos[0], pri0.basePos[1], pri1.basePos[0], pri1.basePos[1], out _, out _, out _, out _);
- float blen = math.sqrt(bsqlen);
- //blen *= 0.7f;
- if (blen < 0.005f)
- return;
- //if (thickness > blen)
- // Debug.Log($"EE thickness:{thickness}, blen:{blen}");
- thickness = math.min(thickness, blen);
- scr = thickness * Define.System.SelfCollisionSCR;
- }
-#endif
-
- // 接触判定
- if (l > (thickness + scr))
- return;
-
- //=========================================================
- // 接触情報作成
- //=========================================================
- var contact = new EdgeEdgeContact();
- contact.flagAndTeamId0 = pri0.flagAndTeamId | Flag_Enable;
- contact.flagAndTeamId1 = pri1.flagAndTeamId;
- contact.thickness = (half)thickness;
- contact.s = (half)s;
- contact.t = (half)t;
- contact.n = (half3)n;
- contact.edgeInvMass0 = (half2)pri0.invMass.xy;
- contact.edgeInvMass1 = (half2)pri1.invMass.xy;
- contact.edgeParticleIndex0 = pri0.particleIndices.xy;
- contact.edgeParticleIndex1 = pri1.particleIndices.xy;
- //Debug.Log(contact.ToString());
-
- // キューへの振り分け
- edgeEdgeContactQueue.Enqueue(contact);
- }
}
- [BurstCompile]
- struct EdgeEdgeToListJob : IJob
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static int3 GetGrid(float3 pos, float gridSize)
{
+ //Debug.Assert(gridSize > 0.0f);
+ return new int3(math.floor(pos / gridSize));
+ }
+
+ //=========================================================================================
+ // Contact
+ //=========================================================================================
+ [BurstCompile]
+ unsafe internal struct SelfStep_DetectionContactJob : IJobParallelFor
+ {
+ public int updateIndex;
+ public int workerCount;
+ public int teamCount;
+
+ // team
[Unity.Collections.ReadOnly]
- public NativeQueue edgeEdgeContactQueue;
-
- [NativeDisableParallelForRestriction]
- public NativeList edgeEdgeContactList;
-
- public void Execute()
- {
- edgeEdgeContactList.Clear();
- if (edgeEdgeContactQueue.Count > 0)
- edgeEdgeContactList.AddRange(edgeEdgeContactQueue.ToArray(Allocator.Temp));
- }
- }
-
- [BurstCompile]
- struct PointTriangleToListJob : IJob
- {
+ public NativeList batchSelfTeamList;
[Unity.Collections.ReadOnly]
- public NativeQueue pointTriangleContactQueue;
+ public NativeArray teamDataArray;
- [NativeDisableParallelForRestriction]
- public NativeList pointTriangleContactList;
-
- public void Execute()
- {
- pointTriangleContactList.Clear();
- if (pointTriangleContactQueue.Count > 0)
- pointTriangleContactList.AddRange(pointTriangleContactQueue.ToArray(Allocator.Temp));
- }
- }
-
- JobHandle UpdateBroadPhase(JobHandle jobHandle)
- {
- var sm = MagicaManager.Simulation;
-
- // EdgeEdge
- var updateJob1 = new UpdateEdgeEdgeBroadPhaseJob()
- {
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- oldPosArray = sm.oldPosArray.GetNativeArray(),
- edgeEdgeContactList = edgeEdgeContactList,
- };
- jobHandle = updateJob1.Schedule(edgeEdgeContactList, 16, jobHandle);
-
- // PointTriangle
- var updateJob2 = new UpdatePointTriangleBroadPhaseJob()
- {
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- oldPosArray = sm.oldPosArray.GetNativeArray(),
- pointTriangleContactList = pointTriangleContactList,
- };
- jobHandle = updateJob2.Schedule(pointTriangleContactList, 16, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct UpdateEdgeEdgeBroadPhaseJob : IJobParallelForDefer
- {
// particle
[Unity.Collections.ReadOnly]
public NativeArray nextPosArray;
[Unity.Collections.ReadOnly]
public NativeArray oldPosArray;
+ // self collision
+ [Unity.Collections.ReadOnly]
+ public NativeArray primitiveArrayB;
+ [Unity.Collections.ReadOnly]
+ public NativeArray uniformGridStartCountBuffer;
+
+ // buffer
[NativeDisableParallelForRestriction]
- public NativeList edgeEdgeContactList;
+ public NativeQueue.ParallelWriter contactQueue;
+
+ // 1チーム6インデックス分割 x ワーカー数
+ public void Execute(int index)
+ {
+ // 各ベースポインタ
+ TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr();
+
+ // チームインデックス
+ int teamIndex = index / (6 * workerCount);
+ index = index % (6 * workerCount);
+ int teamId = batchSelfTeamList[teamIndex];
+ ref var tdata = ref *(teamPt + teamId);
+ if (updateIndex >= tdata.updateCount)
+ return;
+ if (tdata.IsProcess == false)
+ return;
+ if (tdata.ParticleCount == 0)
+ return;
+
+ // ワーカー番号
+ int workerIndex = index / 6;
+ index = index % 6;
+
+ // セルフコリジョン or 相互コリジョン
+ int collisionMode = index / 3;
+ index = index % 3;
+
+ // コリジョン種類
+ int contactKind = index;
+
+ uint myKind = 0, tarKind = 0;
+ switch (contactKind)
+ {
+ case ContactType_EdgeEdge:
+ myKind = KindEdge;
+ tarKind = KindEdge;
+ break;
+ case ContactType_PointTriangle:
+ myKind = KindPoint;
+ tarKind = KindTriangle;
+ break;
+ case ContactType_TrianglePoint:
+ myKind = KindTriangle;
+ tarKind = KindPoint;
+ break;
+ }
+
+ // ■コンタクトバッファ作成(ステップ初回のみ)
+
+ if (collisionMode == 0)
+ {
+ // セルフコリジョン
+ // セルフコリジョンではTrianglePointは不要
+ if (contactKind == ContactType_TrianglePoint)
+ return;
+
+ int selfFlag = TeamManager.Flag_Self_EdgeEdge + (contactKind * 3);
+ if (tdata.flag.IsSet(selfFlag))
+ {
+ //Debug.Log($"Self detection contact. myTeam:{teamId}, myKind:{myKind}, tarTeam:{teamId}, tarKind:{tarKind}");
+
+ DetectionContacts(
+ workerCount,
+ workerIndex,
+ teamId,
+ ref tdata,
+ myKind,
+ teamId,
+ ref tdata,
+ tarKind,
+ ref nextPosArray,
+ ref oldPosArray,
+ ref primitiveArrayB,
+ ref uniformGridStartCountBuffer,
+ ref contactQueue
+ );
+ }
+ }
+ else if (collisionMode == 1 && tdata.syncTeamId > 0)
+ {
+ // 相互コリジョン
+ ref var stdata = ref *(teamPt + tdata.syncTeamId);
+ int syncFlag = TeamManager.Flag_Sync_EdgeEdge + (contactKind * 3);
+ if (tdata.flag.IsSet(syncFlag))
+ {
+ //Debug.Log($"Sync detection contact. myTeam:{teamId}, myKind:{myKind}, tarTeam:{teamId}, tarKind:{tarKind}");
+
+ DetectionContacts(
+ workerCount,
+ workerIndex,
+ teamId,
+ ref tdata,
+ myKind,
+ tdata.syncTeamId,
+ ref stdata,
+ tarKind,
+ ref nextPosArray,
+ ref oldPosArray,
+ ref primitiveArrayB,
+ ref uniformGridStartCountBuffer,
+ ref contactQueue
+ );
+ }
+ }
+
+ //Debug.Log($"Detection contact. team:{teamId}, collisionMode:{collisionMode}, contactKind:{contactKind}, writeCount:{writeCount}");
+ }
+ }
+
+ unsafe static void DetectionContacts(
+ int workerCount,
+ int workerIndex,
+ // my
+ int myTeamId,
+ ref TeamManager.TeamData myTeam,
+ uint myKind,
+ // target
+ int targetTeamId,
+ ref TeamManager.TeamData targetTeam,
+ uint targetKind,
+ // particle
+ ref NativeArray nextPosArray,
+ ref NativeArray oldPosArray,
+ // self collision
+ ref NativeArray primitiveArrayB,
+ ref NativeArray uniformGridStartCountBuffer,
+ // contact buffer
+ ref NativeQueue.ParallelWriter contactQueue
+ )
+ {
+ Primitive* pt = (Primitive*)primitiveArrayB.GetUnsafeReadOnlyPtr();
+ GridInfo* gt = (GridInfo*)uniformGridStartCountBuffer.GetUnsafeReadOnlyPtr();
+
+ // 参照元
+ DataChunk myPriChunk = myKind == KindPoint ? myTeam.selfPointChunk : (myKind == KindEdge ? myTeam.selfEdgeChunk : myTeam.selfTriangleChunk);
+ if (myPriChunk.IsValid == false)
+ return;
+
+ // ワーカー分散による範囲
+ int2 range = MathUtility.CalcSplitRange(myPriChunk.dataLength, workerCount, workerIndex);
+ myPriChunk.startIndex += range.x;
+ myPriChunk.dataLength = range.y - range.x;
+
+ // 対象
+ DataChunk tarPriChunk = targetKind == KindPoint ? targetTeam.selfPointChunk : (targetKind == KindEdge ? targetTeam.selfEdgeChunk : targetTeam.selfTriangleChunk);
+ if (tarPriChunk.IsValid == false)
+ return;
+ int gridBufferStart = tarPriChunk.startIndex;
+ int gridBufferIndex = gridBufferStart;
+ int gridBufferCount = 0;
+ switch (targetKind)
+ {
+ case KindPoint:
+ gridBufferCount = targetTeam.selfPointGridCount;
+ break;
+ case KindEdge:
+ gridBufferCount = targetTeam.selfEdgeGridCount;
+ break;
+ case KindTriangle:
+ gridBufferCount = targetTeam.selfTriangleGridCount;
+ break;
+ }
+ float maxPrimitiveSize = targetTeam.selfMaxPrimitiveSize;
+ float gridSize = targetTeam.selfGridSize;
+
+ // 重複判定の有無
+ bool duplicateDetection = (myTeamId == targetTeamId && myKind == targetKind);
+
+ // プリミティブの接続判定
+ bool connectionCheck = myTeamId == targetTeamId;
+
+ // 接触タイプ
+ bool primitiveFlip = false;
+ byte contactType = ContactType_EdgeEdge;
+ if (myKind == KindPoint && targetKind == KindTriangle)
+ contactType = ContactType_PointTriangle;
+ else if (myKind == KindTriangle && targetKind == KindPoint)
+ {
+ contactType = ContactType_PointTriangle;
+ primitiveFlip = true;
+ }
+
+ // プリミティブごと
+ GridInfo searchGridInfo = new GridInfo();
+ int priIndex = myPriChunk.startIndex;
+ for (int i = 0; i < myPriChunk.dataLength; i++, priIndex++)
+ {
+ ref var p = ref *(pt + priIndex);
+
+ // 無効判定
+ if (p.IsIgnore())
+ continue;
+
+ bool pFix = (p.flag & Flag_AllFix) != 0;
+
+ // このプリミティブの検索範囲
+ float3 areaMin = p.aabb.Min - maxPrimitiveSize * 0.5f;
+ float3 areaMax = p.aabb.Max + maxPrimitiveSize * 0.5f;
+
+ // グリッド範囲に変換する
+ int3 startGrid = GetGrid(areaMin, gridSize);
+ int3 endGrid = GetGrid(areaMax, gridSize);
+
+ // グリッド範囲を調べる
+ int3 currentGrid = startGrid;
+ bool finish = false;
+ while (finish == false)
+ {
+ // グリッド情報検索(ハッシュ値による2分探索)
+ int currentHash = currentGrid.GetHashCode();
+ searchGridInfo.hash = currentHash;
+ int infoIndex = NativeSortExtension.BinarySearch(gt + gridBufferStart, gridBufferCount, searchGridInfo);
+ if (infoIndex >= 0)
+ {
+ // このグリッドにはプリミティブが存在する
+ ref var gridInfo = ref *(gt + gridBufferStart + infoIndex);
+ int startPriIndex2 = gridInfo.start;
+ int endPriIndex2 = startPriIndex2 + gridInfo.count;
+
+ // 重複判定:グリッド全体が現在のpriIndexより下ならば検索不要
+ if (duplicateDetection == false || endPriIndex2 >= priIndex)
+ {
+ // 重複判定:現在のpindexより上のものだけを調べる
+ int priIndex2 = duplicateDetection ? math.max(startPriIndex2, priIndex) : startPriIndex2;
+ for (; priIndex2 < endPriIndex2; priIndex2++)
+ {
+ if (duplicateDetection && priIndex == priIndex2)
+ continue;
+
+ ref var p2 = ref *(pt + priIndex2);
+
+ // AABB判定
+ if (p.aabb.Overlaps(p2.aabb) == false)
+ continue;
+
+ // 無効判定
+ if (p2.IsIgnore())
+ continue;
+
+ // 両方のプリミティブが完全固定ならば無効
+ if (pFix && ((p2.flag & Flag_AllFix) != 0))
+ continue;
+
+ // プリミティブ同士が接続している場合は無効
+ if (connectionCheck && p.AnyParticle(ref p2))
+ continue;
+
+ // !衝突検出!
+ // コンタクトバッファ生成
+ var contact = new ContactInfo()
+ {
+ primitiveIndex0 = primitiveFlip == false ? priIndex : priIndex2,
+ primitiveIndex1 = primitiveFlip == false ? priIndex2 : priIndex,
+ contactType = contactType,
+ thickness = (half)(p.thickness + p2.thickness),
+ };
+
+ // コンタクト変位判定
+ UpdateContactInfo(
+ ref contact,
+ pt,
+ ref nextPosArray,
+ ref oldPosArray,
+ Define.System.SelfCollisionSCR,
+ true
+ );
+ if (contact.enable == 0)
+ continue;
+
+ contactQueue.Enqueue(contact);
+ //Debug.Log($"Contact! myTeamId:{myTeamId}, myKind:{myKind}, targetTeamId:{targetTeamId}, targetKind:{targetKind}, ({priIndex}->{priIndex2})");
+ }
+ }
+ }
+
+ // next
+ currentGrid.x++;
+ if (currentGrid.x > endGrid.x)
+ {
+ currentGrid.x = startGrid.x;
+ currentGrid.y++;
+ if (currentGrid.y > endGrid.y)
+ {
+ currentGrid.y = startGrid.y;
+ currentGrid.z++;
+ if (currentGrid.z > endGrid.z)
+ {
+ finish = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ [BurstCompile]
+ unsafe internal struct SelfStep_ConvertContactListJob : IJob
+ {
+ [Unity.Collections.ReadOnly]
+ public NativeQueue contactQueue;
+
+ [NativeDisableParallelForRestriction]
+ public NativeList contactList;
+
+ public void Execute()
+ {
+ contactList.Clear();
+ if (contactQueue.Count > 0)
+ contactList.AddRange(contactQueue.ToArray(Allocator.Temp));
+
+ //Debug.Log($"contact count:{contactList.Length}");
+ }
+ }
+
+ [BurstCompile]
+ unsafe internal struct SelfStep_UpdateContactJob : IJobParallelForDefer
+ {
+ public bool first;
+ [NativeDisableParallelForRestriction]
+ public NativeList contactList;
+
+ // particle
+ [Unity.Collections.ReadOnly]
+ public NativeArray nextPosArray;
+ [Unity.Collections.ReadOnly]
+ public NativeArray oldPosArray;
+ // self collision
+ [Unity.Collections.ReadOnly]
+ public NativeArray primitiveArrayB;
// コンタクトごと
public void Execute(int index)
{
- var contact = edgeEdgeContactList[index];
+ Primitive* pt = (Primitive*)primitiveArrayB.GetUnsafeReadOnlyPtr();
+ ContactInfo* ct = (ContactInfo*)contactList.GetUnsafePtr();
- var oldPosA0 = oldPosArray[contact.edgeParticleIndex0.x];
- var oldPosA1 = oldPosArray[contact.edgeParticleIndex0.y];
- var oldPosB0 = oldPosArray[contact.edgeParticleIndex1.x];
- var oldPosB1 = oldPosArray[contact.edgeParticleIndex1.y];
+ ref ContactInfo contact = ref *(ct + index);
- var nextPosA0 = nextPosArray[contact.edgeParticleIndex0.x];
- var nextPosA1 = nextPosArray[contact.edgeParticleIndex0.y];
- var nextPosB0 = nextPosArray[contact.edgeParticleIndex1.x];
- var nextPosB1 = nextPosArray[contact.edgeParticleIndex1.y];
+ // 反復計算用にコンタクト情報を更新する
+ UpdateContactInfo(
+ ref contact,
+ pt,
+ ref nextPosArray,
+ ref oldPosArray,
+ Define.System.SelfCollisionSCR,
+ first
+ );
+ }
+ }
+
+ unsafe static void UpdateContactInfo(
+ ref ContactInfo contact,
+ Primitive* pt,
+ ref NativeArray nextPosArray,
+ ref NativeArray oldPosArray,
+ float scrScale,
+ bool first
+ )
+ {
+ ref var p0 = ref *(pt + contact.primitiveIndex0);
+ ref var p1 = ref *(pt + contact.primitiveIndex1);
+
+ float thickness = contact.thickness;
+ float scr = thickness * scrScale;
+
+ contact.enable = 0;
+
+ // AABB
+
+
+ // コンタクト解決
+ if (contact.contactType == ContactType_EdgeEdge)
+ {
+ var nextPosA0 = nextPosArray[p0.particleIndices.x];
+ var nextPosA1 = nextPosArray[p0.particleIndices.y];
+ var nextPosB0 = nextPosArray[p1.particleIndices.x];
+ var nextPosB1 = nextPosArray[p1.particleIndices.y];
+ var oldPosA0 = oldPosArray[p0.particleIndices.x];
+ var oldPosA1 = oldPosArray[p0.particleIndices.y];
+ var oldPosB0 = oldPosArray[p1.particleIndices.x];
+ var oldPosB1 = oldPosArray[p1.particleIndices.y];
// 移動前の2つの線分の最近接点
- float s, t;
- float3 cA, cB;
- float csqlen = MathUtility.ClosestPtSegmentSegment(oldPosA0, oldPosA1, oldPosB0, oldPosB1, out s, out t, out cA, out cB);
+ float csqlen = MathUtility.ClosestPtSegmentSegment(oldPosA0, oldPosA1, oldPosB0, oldPosB1, out var s, out var t, out var cA, out var cB);
float clen = math.sqrt(csqlen); // 最近接点の距離
if (clen < 1e-09f)
return;
@@ -1926,596 +1567,708 @@ namespace MagicaCloth2
float l0 = math.dot(n, da);
float l1 = math.dot(n, db);
float l = clen + l0 - l1;
+ if (l > (thickness + scr))
+ return;
- // 接触判定
- float scr = contact.thickness;
- if (l > (contact.thickness + scr))
- {
- contact.flagAndTeamId0 &= ~Flag_Enable;
- }
- else
- {
- contact.flagAndTeamId0 |= Flag_Enable;
- contact.s = (half)s;
- contact.t = (half)t;
- contact.n = (half3)n;
- }
-
- edgeEdgeContactList[index] = contact;
+ // 有効
+ contact.enable = 1;
+ contact.s = (half)s;
+ contact.t = (half)t;
+ contact.n = (half3)n;
}
- }
-
- [BurstCompile]
- struct UpdatePointTriangleBroadPhaseJob : IJobParallelForDefer
- {
- // particle
- [Unity.Collections.ReadOnly]
- public NativeArray nextPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray oldPosArray;
-
- [NativeDisableParallelForRestriction]
- public NativeList pointTriangleContactList;
-
- // コンタクトごと
- public void Execute(int index)
+ else if (contact.contactType == ContactType_PointTriangle)
{
- var contact = pointTriangleContactList[index];
+ var nextPosA0 = nextPosArray[p0.particleIndices.x];
+ var oldPosA0 = oldPosArray[p0.particleIndices.x];
- bool enable = false;
-
- var oldPosA = oldPosArray[contact.pointParticleIndex];
- var oldPosB0 = oldPosArray[contact.triangleParticleIndex.x];
- var oldPosB1 = oldPosArray[contact.triangleParticleIndex.y];
- var oldPosB2 = oldPosArray[contact.triangleParticleIndex.z];
-
- var nextPosA = nextPosArray[contact.pointParticleIndex];
- var nextPosB0 = nextPosArray[contact.triangleParticleIndex.x];
- var nextPosB1 = nextPosArray[contact.triangleParticleIndex.y];
- var nextPosB2 = nextPosArray[contact.triangleParticleIndex.z];
+ var nextPosB0 = nextPosArray[p1.particleIndices.x];
+ var nextPosB1 = nextPosArray[p1.particleIndices.y];
+ var nextPosB2 = nextPosArray[p1.particleIndices.z];
+ var oldPosB0 = oldPosArray[p1.particleIndices.x];
+ var oldPosB1 = oldPosArray[p1.particleIndices.y];
+ var oldPosB2 = oldPosArray[p1.particleIndices.z];
// 変位
- var dA = nextPosA - oldPosA;
+ var dA = nextPosA0 - oldPosA0;
var dB0 = nextPosB0 - oldPosB0;
var dB1 = nextPosB1 - oldPosB1;
var dB2 = nextPosB2 - oldPosB2;
- //=========================================================
// 衝突予測と格納
- //=========================================================
- float3 uvw, cp;
+ float3 cp;
// 移動前ポイントと移動前トライアングルへの最近接点
- cp = MathUtility.ClosestPtPointTriangle(oldPosA, oldPosB0, oldPosB1, oldPosB2, out uvw);
+ cp = MathUtility.ClosestPtPointTriangle(oldPosA0, oldPosB0, oldPosB1, oldPosB2, out var uvw);
// 最近接点座標の変位を求める
float3 dt = dB0 * uvw.x + dB1 * uvw.y + dB2 * uvw.z;
// 最近接点ベクトル
- float3 cv = cp - oldPosA;
+ float3 cv = cp - oldPosA0;
float cvlen = math.length(cv);
- if (cvlen > Define.System.Epsilon)
+ if (cvlen <= Define.System.Epsilon)
+ return;
+
+ var n = cv / cvlen;
+
+ // 変位dp,dtをnに投影して距離チェック
+ float l0 = math.dot(n, dA);
+ float l1 = math.dot(n, dt);
+ float l = cvlen - l0 + l1;
+
+ // 接続判定
+ if (l >= (thickness + scr))
+ return;
+
+ // 方向性判定
+ // !signの算出はオリジナルでは登録時に1回しか行っていない。
+ float sign = contact.s;
+ if (first)
{
- var n = cv / cvlen;
+ // 移動前トライアングル法線
+ float3 otn = MathUtility.TriangleNormal(oldPosB0, oldPosB1, oldPosB2);
- // 変位dp,dtをnに投影して距離チェック
- float l0 = math.dot(n, dA);
- float l1 = math.dot(n, dt);
- float l = cvlen - l0 + l1;
+ // 移動前のパーティクル方向性
+ n = math.normalize(oldPosA0 - cp);
+ float dot = math.dot(otn, n);
+ // 移動前にトライアングル面に対してほぼ水平ならば無視する
+ if (math.abs(dot) >= Define.System.SelfCollisionPointTriangleAngleCos)
+ sign = math.sign(dot);
+ else
+ return;
+ }
+ contact.s = (half)sign;
- // 接続判定
- float scr = contact.thickness;
- if (l < (contact.thickness + scr))
+ // 有効
+ contact.enable = 1;
+ }
+ }
+
+ [BurstCompile]
+ unsafe internal struct SelfStep_SolverContactJob : IJobParallelForDefer
+ {
+ // particle
+ [Unity.Collections.ReadOnly]
+ public NativeArray nextPosArray;
+
+ // self collision
+ [Unity.Collections.ReadOnly]
+ public NativeArray primitiveArrayB;
+ [Unity.Collections.ReadOnly]
+ public NativeList contactList;
+
+ // buffer2
+ [NativeDisableParallelForRestriction]
+ public NativeArray tempVectorBufferA;
+ [NativeDisableParallelForRestriction]
+ public NativeArray tempCountBuffer;
+
+ // コンタクトごと
+ public void Execute(int index)
+ {
+ ContactInfo* ct = (ContactInfo*)contactList.GetUnsafeReadOnlyPtr();
+ Primitive* pt = (Primitive*)primitiveArrayB.GetUnsafeReadOnlyPtr();
+ int* cntPt = (int*)tempCountBuffer.GetUnsafePtr();
+ int* sumPt = (int*)tempVectorBufferA.GetUnsafePtr();
+
+ ref var contact = ref *(ct + index);
+
+ // 解決
+ if (contact.enable == 0)
+ return;
+
+ ref var p0 = ref *(pt + contact.primitiveIndex0);
+ ref var p1 = ref *(pt + contact.primitiveIndex1);
+
+ float thickness = contact.thickness;
+ float scr = thickness * Define.System.SelfCollisionSCR;
+
+ // コンタクト解決
+ if (contact.contactType == ContactType_EdgeEdge)
+ {
+ var nextPosA0 = nextPosArray[p0.particleIndices.x];
+ var nextPosA1 = nextPosArray[p0.particleIndices.y];
+ var nextPosB0 = nextPosArray[p1.particleIndices.x];
+ var nextPosB1 = nextPosArray[p1.particleIndices.y];
+
+ float s = contact.s;
+ float t = contact.t;
+ float3 n = contact.n;
+
+ // 移動前に接触判定を行った位置の移動後の位置a/bと方向ベクトル
+ float3 a = math.lerp(nextPosA0, nextPosA1, s);
+ float3 b = math.lerp(nextPosB0, nextPosB1, t);
+ float3 v = a - b;
+
+ // 接触法線に現在の距離を投影させる
+ float l = math.dot(n, v);
+ //Debug.Log($"A({pA0}-{pA1}), B({pB0}-{pB1}) s:{s}, t:{t} l:{l}");
+ if (l > thickness)
+ return;
+
+ float invMassA0 = p0.invMass.x;
+ float invMassA1 = p0.invMass.y;
+ float invMassB0 = p1.invMass.x;
+ float invMassB1 = p1.invMass.y;
+
+ // 離す距離
+ float C = thickness - l;
+
+ // お互いを離す
+ float b0 = 1.0f - s;
+ float b1 = s;
+ float b2 = 1.0f - t;
+ float b3 = t;
+ float3 grad0 = n * b0;
+ float3 grad1 = n * b1;
+ float3 grad2 = -n * b2;
+ float3 grad3 = -n * b3;
+
+ float S = invMassA0 * b0 * b0 + invMassA1 * b1 * b1 + invMassB0 * b2 * b2 + invMassB1 * b3 * b3;
+ if (S == 0.0f)
+ return;
+
+ S = C / S;
+
+ float3 _A0 = S * invMassA0 * grad0;
+ float3 _A1 = S * invMassA1 * grad1;
+ float3 _B0 = S * invMassB0 * grad2;
+ float3 _B1 = S * invMassB1 * grad3;
+
+#if true
+ // 書き込み
+ if ((p0.flag & Flag_FixIntersect0) == 0)
{
- enable = true;
+ InterlockUtility.AddFloat3(p0.particleIndices.x, _A0, cntPt, sumPt);
+ }
+ if ((p0.flag & Flag_FixIntersect1) == 0)
+ {
+ InterlockUtility.AddFloat3(p0.particleIndices.y, _A1, cntPt, sumPt);
+ }
+ if ((p1.flag & Flag_FixIntersect0) == 0)
+ {
+ InterlockUtility.AddFloat3(p1.particleIndices.x, _B0, cntPt, sumPt);
+ }
+ if ((p1.flag & Flag_FixIntersect1) == 0)
+ {
+ InterlockUtility.AddFloat3(p1.particleIndices.y, _B1, cntPt, sumPt);
+ }
+#endif
+ }
+ else if (contact.contactType == ContactType_PointTriangle)
+ {
+ // トライアングル情報
+ float3 nextPos0 = nextPosArray[p1.particleIndices.x];
+ float3 nextPos1 = nextPosArray[p1.particleIndices.y];
+ float3 nextPos2 = nextPosArray[p1.particleIndices.z];
+ float invMass0 = p1.invMass.x;
+ float invMass1 = p1.invMass.y;
+ float invMass2 = p1.invMass.z;
+
+ // 移動後トライアングル法線
+ float3 tn = MathUtility.TriangleNormal(nextPos0, nextPos1, nextPos2);
+
+ // 対象パーティクル情報
+ float3 nextPos = nextPosArray[p0.particleIndices.x];
+ float invMass = p0.invMass.x;
+
+ // 衝突の解決
+ // 移動後ポイントと移動後トライアングルへの最近接点
+ float3 uvw;
+ MathUtility.ClosestPtPointTriangle(nextPos, nextPos0, nextPos1, nextPos2, out uvw);
+
+ // 押し出し方向(移動後のトライアングル法線)
+ // 移動前に裏側ならば反転させる
+ float sign = contact.s;
+ float3 n = tn * sign;
+
+ // 押し出し法線方向に投影した距離
+ float dist = math.dot(n, nextPos - nextPos0);
+ //Debug.Log($"dist:{dist}");
+ if (dist >= thickness)
+ return;
+
+ // 引き離す距離
+ float restDist = thickness;
+
+ // 押し出し
+ float C = dist - restDist;
+
+ float3 grad = n;
+ float3 grad0 = -n * uvw[0];
+ float3 grad1 = -n * uvw[1];
+ float3 grad2 = -n * uvw[2];
+
+ float s = invMass + invMass0 * uvw.x * uvw.x + invMass1 * uvw.y * uvw.y + invMass2 * uvw.z * uvw.z;
+ if (s == 0.0f)
+ return;
+ s = C / s;
+
+ float3 corr = -s * invMass * grad;
+ float3 corr0 = -s * invMass0 * grad0;
+ float3 corr1 = -s * invMass1 * grad1;
+ float3 corr2 = -s * invMass2 * grad2;
+
+#if true
+ // 書き込み
+ if ((p0.flag & Flag_FixIntersect0) == 0)
+ {
+ InterlockUtility.AddFloat3(p0.particleIndices.x, corr, cntPt, sumPt);
+ }
+ if ((p1.flag & Flag_FixIntersect0) == 0)
+ {
+ InterlockUtility.AddFloat3(p1.particleIndices.x, corr0, cntPt, sumPt);
+ }
+ if ((p1.flag & Flag_FixIntersect1) == 0)
+ {
+ InterlockUtility.AddFloat3(p1.particleIndices.y, corr1, cntPt, sumPt);
+ }
+ if ((p1.flag & Flag_FixIntersect2) == 0)
+ {
+ InterlockUtility.AddFloat3(p1.particleIndices.z, corr2, cntPt, sumPt);
+ }
+#endif
+ }
+ }
+ }
+
+ [BurstCompile]
+ unsafe internal struct SelfStep_SumContactJob : IJobParallelFor
+ {
+ public int updateIndex;
+
+ // team
+ [Unity.Collections.ReadOnly]
+ public NativeList batchSelfTeamList;
+ [Unity.Collections.ReadOnly]
+ public NativeArray teamDataArray;
+
+ // particle
+ [NativeDisableParallelForRestriction]
+ public NativeArray nextPosArray;
+
+ // buffer2
+ [NativeDisableParallelForRestriction]
+ public NativeArray tempVectorBufferA;
+ [NativeDisableParallelForRestriction]
+ public NativeArray tempCountBuffer;
+
+ // ローカルチームインデックスごと
+ public void Execute(int localIndex)
+ {
+ TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr();
+ int* cntPt = (int*)tempCountBuffer.GetUnsafePtr();
+ int* sumPt = (int*)tempVectorBufferA.GetUnsafePtr();
+ float3* nextPosT = (float3*)nextPosArray.GetUnsafePtr();
+
+ int teamId = batchSelfTeamList[localIndex];
+ ref var tdata = ref *(teamPt + teamId);
+ if (tdata.IsProcess == false)
+ return;
+ if (tdata.ParticleCount == 0)
+ return;
+
+ if (updateIndex < tdata.updateCount)
+ {
+ int pindex = tdata.particleChunk.startIndex;
+ int pindex2 = pindex * 3;
+ for (int i = 0; i < tdata.particleChunk.dataLength; i++, pindex++, pindex2 += 3)
+ {
+ int cnt = cntPt[pindex];
+ if (cnt > 0)
+ {
+ float3 add = new float3(sumPt[pindex2], sumPt[pindex2 + 1], sumPt[pindex2 + 2]);
+ add /= cnt;
+ // データは固定小数点なので戻す
+ add *= InterlockUtility.ToFloat;
+
+ // 反映
+ *(nextPosT + pindex) += add;
+ }
}
}
- if (enable)
- contact.flagAndTeamId0 |= Flag_Enable;
- else
- contact.flagAndTeamId0 &= ~Flag_Enable;
-
- pointTriangleContactList[index] = contact;
- }
- }
-
- [BurstCompile]
- unsafe struct SolverEdgeEdgeJob : IJobParallelForDefer
- {
- // particle
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
-
- // contact
- [Unity.Collections.ReadOnly]
- public NativeArray edgeEdgeContactArray;
-
- // output
- [NativeDisableParallelForRestriction]
- public NativeArray countArray;
- [NativeDisableParallelForRestriction]
- public NativeArray sumArray;
-
- // コンタクトごと
- public void Execute(int index)
- {
- //Debug.Log($"EdgeEdgeContactCount:{edgeEdgeContactQueue.Count}");
-
- var contact = edgeEdgeContactArray[index];
- if ((contact.flagAndTeamId0 & Flag_Enable) == 0)
- return;
-
- var nextPosA0 = nextPosArray[contact.edgeParticleIndex0.x];
- var nextPosA1 = nextPosArray[contact.edgeParticleIndex0.y];
- var nextPosB0 = nextPosArray[contact.edgeParticleIndex1.x];
- var nextPosB1 = nextPosArray[contact.edgeParticleIndex1.y];
-
- float s = contact.s;
- float t = contact.t;
- float3 n = contact.n;
- float thickness = contact.thickness;
-
- // 移動前に接触判定を行った位置の移動後の位置a/bと方向ベクトル
- float3 a = math.lerp(nextPosA0, nextPosA1, s);
- float3 b = math.lerp(nextPosB0, nextPosB1, t);
- float3 v = a - b;
-
- // 接触法線に現在の距離を投影させる
- float l = math.dot(n, v);
- //Debug.Log($"A({pA0}-{pA1}), B({pB0}-{pB1}) s:{s}, t:{t} l:{l}");
- if (l > thickness)
- return;
-
- float invMassA0 = contact.edgeInvMass0.x;
- float invMassA1 = contact.edgeInvMass0.y;
- float invMassB0 = contact.edgeInvMass1.x;
- float invMassB1 = contact.edgeInvMass1.y;
-
- // 離す距離
- float C = thickness - l;
-
- // お互いを離す
- float b0 = 1.0f - s;
- float b1 = s;
- float b2 = 1.0f - t;
- float b3 = t;
- float3 grad0 = n * b0;
- float3 grad1 = n * b1;
- float3 grad2 = -n * b2;
- float3 grad3 = -n * b3;
-
- float S = invMassA0 * b0 * b0 + invMassA1 * b1 * b1 + invMassB0 * b2 * b2 + invMassB1 * b3 * b3;
- if (S == 0.0f)
- return;
-
- S = C / S;
-
- float3 _A0 = S * invMassA0 * grad0;
- float3 _A1 = S * invMassA1 * grad1;
- float3 _B0 = S * invMassB0 * grad2;
- float3 _B1 = S * invMassB1 * grad3;
-
- //=====================================================
- // 書き込み
- //=====================================================
- int* cntPt = (int*)countArray.GetUnsafePtr();
- int* sumPt = (int*)sumArray.GetUnsafePtr();
- if ((contact.flagAndTeamId0 & Flag_Fix0) == 0)
- InterlockUtility.AddFloat3(contact.edgeParticleIndex0.x, _A0, cntPt, sumPt);
- //nextPosArray[contact.edgeParticleIndex0.x] = nextPosA0 + _A0;
- if ((contact.flagAndTeamId0 & Flag_Fix1) == 0)
- InterlockUtility.AddFloat3(contact.edgeParticleIndex0.y, _A1, cntPt, sumPt);
- //nextPosArray[contact.edgeParticleIndex0.y] = nextPosA1 + _A1;
- if ((contact.flagAndTeamId1 & Flag_Fix0) == 0)
- InterlockUtility.AddFloat3(contact.edgeParticleIndex1.x, _B0, cntPt, sumPt);
- //nextPosArray[contact.edgeParticleIndex1.x] = nextPosB0 + _B0;
- if ((contact.flagAndTeamId1 & Flag_Fix1) == 0)
- InterlockUtility.AddFloat3(contact.edgeParticleIndex1.y, _B1, cntPt, sumPt);
- //nextPosArray[contact.edgeParticleIndex1.y] = nextPosB1 + _B1;
- }
- }
-
- [BurstCompile]
- unsafe struct SolverPointTriangleJob : IJobParallelForDefer
- {
- // particle
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
-
- // contact
- [Unity.Collections.ReadOnly]
- public NativeArray pointTriangleContactArray;
-
- // output
- [NativeDisableParallelForRestriction]
- public NativeArray countArray;
- [NativeDisableParallelForRestriction]
- public NativeArray sumArray;
-
- // コンタクトごと
- public void Execute(int index)
- {
- //Debug.Log($"PointTriangleContactCount:{pointTriangleContactQueue.Count}");
-
- var contact = pointTriangleContactArray[index];
- if ((contact.flagAndTeamId0 & Flag_Enable) == 0)
- return;
-
- // 接触距離
- float thickness = contact.thickness;
-
- // トライアングル情報
- int3 tp = contact.triangleParticleIndex;
- float3 nextPos0 = nextPosArray[tp.x];
- float3 nextPos1 = nextPosArray[tp.y];
- float3 nextPos2 = nextPosArray[tp.z];
- float invMass0 = contact.triangleInvMass.x;
- float invMass1 = contact.triangleInvMass.y;
- float invMass2 = contact.triangleInvMass.z;
-
- // 移動後トライアングル法線
- float3 tn = MathUtility.TriangleNormal(nextPos0, nextPos1, nextPos2);
-
- // 対象パーティクル情報
- int t_pindex = contact.pointParticleIndex;
- float3 nextPos = nextPosArray[t_pindex];
- float invMass = contact.pointInvMass;
-
- //=====================================================
- // 衝突の解決
- //=====================================================
- // 移動後ポイントと移動後トライアングルへの最近接点
- float3 uvw;
- MathUtility.ClosestPtPointTriangle(nextPos, nextPos0, nextPos1, nextPos2, out uvw);
-
- // 押し出し方向(移動後のトライアングル法線)
- // 移動前に裏側ならば反転させる
- float sign = contact.sign;
- float3 n = tn * sign;
-
- // 押し出し法線方向に投影した距離
- float dist = math.dot(n, nextPos - nextPos0);
- //Debug.Log($"dist:{dist}");
- if (dist >= thickness)
- return;
-
- // 引き離す距離
- float restDist = thickness;
-
- // 押し出し
- float C = dist - restDist;
-
- float3 grad = n;
- float3 grad0 = -n * uvw[0];
- float3 grad1 = -n * uvw[1];
- float3 grad2 = -n * uvw[2];
-
- float s = invMass + invMass0 * uvw.x * uvw.x + invMass1 * uvw.y * uvw.y + invMass2 * uvw.z * uvw.z;
- if (s == 0.0f)
- return;
- s = C / s;
-
- float3 corr = -s * invMass * grad;
- float3 corr0 = -s * invMass0 * grad0;
- float3 corr1 = -s * invMass1 * grad1;
- float3 corr2 = -s * invMass2 * grad2;
-
- //=====================================================
- // 書き込み
- //=====================================================
- int* cntPt = (int*)countArray.GetUnsafePtr();
- int* sumPt = (int*)sumArray.GetUnsafePtr();
- if ((contact.flagAndTeamId0 & Flag_Fix0) == 0)
- InterlockUtility.AddFloat3(t_pindex, corr, cntPt, sumPt);
- //nextPosArray[t_pindex] = nextPos + corr;
- if ((contact.flagAndTeamId1 & Flag_Fix0) == 0)
- InterlockUtility.AddFloat3(tp.x, corr0, cntPt, sumPt);
- //nextPosArray[tp.x] = nextPos0 + corr0;
- if ((contact.flagAndTeamId1 & Flag_Fix1) == 0)
- InterlockUtility.AddFloat3(tp.y, corr1, cntPt, sumPt);
- //nextPosArray[tp.y] = nextPos1 + corr1;
- if ((contact.flagAndTeamId1 & Flag_Fix2) == 0)
- InterlockUtility.AddFloat3(tp.z, corr2, cntPt, sumPt);
- //nextPosArray[tp.z] = nextPos2 + corr2;
-
- //Debug.Log($"Solve:{contact.ToString()}");
+ // バッファクリア
+ int pindexB = tdata.particleChunk.startIndex;
+ for (int i = 0; i < tdata.particleChunk.dataLength; i++, pindexB++)
+ {
+ tempCountBuffer[pindexB] = 0;
+ tempVectorBufferA[pindexB] = 0;
+ }
}
}
//=========================================================================================
- ///
- /// 交差(絡まり)の解決
- ///
- ///
- ///
- unsafe JobHandle SolveIntersect(JobHandle jobHandle)
- {
- if (IntersectCount == 0)
- return jobHandle;
-
- var tm = MagicaManager.Team;
- var sm = MagicaManager.Simulation;
-
- // 交差フラグクリア
- jobHandle = JobUtility.Fill(intersectFlagArray, intersectFlagArray.Length, 0, jobHandle);
-
- // EdgePrimitiveのnextPos更新
- var updateJob1 = new IntersectUpdatePrimitiveJob()
- {
- kind = KindEdge,
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- primitiveArray = primitiveArray.GetNativeArray(),
- processingArray = sm.processingSelfEdgeEdge.Buffer,
- };
- jobHandle = updateJob1.Schedule(sm.processingSelfEdgeEdge.GetJobSchedulePtr(), 16, jobHandle);
-
- // TrianglePrimitiveのnextPos更新
- var updateJob2 = new IntersectUpdatePrimitiveJob()
- {
- kind = KindTriangle,
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- primitiveArray = primitiveArray.GetNativeArray(),
- processingArray = sm.processingSelfTrianglePoint.Buffer,
- };
- jobHandle = updateJob2.Schedule(sm.processingSelfTrianglePoint.GetJobSchedulePtr(), 16, jobHandle);
-
- // EdgeTriangle交差判定
- // !重い処理なのでステップごとに分割して少しずつ実行する
- int stepCount = sm.SimulationStepCount;
- int execNumber = stepCount % Define.System.SelfCollisionIntersectDiv;
-
- // !正確にはここでは交差を実際には解決しない
- // !交差しているEdgeTriangleのパーティクルにフラグを付け、次のステップのセルフ衝突判定から除外することで絡まりを解く
- // !衝突判定を行わないことでパーティクルは自由になり復元制約の効果で元の姿勢に戻ろうとする(この時からまりが解ける)
- // !この方法は論文にない独自のもので精度も高くないが安価なコストで交差をある程度解消することでできる(ランタイム向き)
-
- // Edgeベース
- var intersectJob1 = new IntersectEdgeTriangleJob()
- {
- mainKind = KindEdge,
- execNumber = execNumber,
- div = Define.System.SelfCollisionIntersectDiv,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- primitiveArray = primitiveArray.GetNativeArray(),
- sortAndSweepArray = sortAndSweepArray.GetNativeArray(),
- processingEdgeEdgeArray = sm.processingSelfEdgeEdge.Buffer,
- intersectFlagArray = intersectFlagArray,
- };
- jobHandle = intersectJob1.Schedule(sm.processingSelfEdgeEdge.GetJobSchedulePtr(), 16, jobHandle);
-
- // Triangleベース
- var intersectJob2 = new IntersectEdgeTriangleJob()
- {
- mainKind = KindTriangle,
- execNumber = execNumber,
- div = Define.System.SelfCollisionIntersectDiv,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- primitiveArray = primitiveArray.GetNativeArray(),
- sortAndSweepArray = sortAndSweepArray.GetNativeArray(),
- processingEdgeEdgeArray = sm.processingSelfTrianglePoint.Buffer,
- intersectFlagArray = intersectFlagArray,
- };
- jobHandle = intersectJob2.Schedule(sm.processingSelfTrianglePoint.GetJobSchedulePtr(), 16, jobHandle);
-
- return jobHandle;
- }
-
+ // Intersect
+ //=========================================================================================
[BurstCompile]
- struct IntersectUpdatePrimitiveJob : IJobParallelForDefer
+ unsafe internal struct SelfDetectionIntersectJob : IJobParallelFor
{
- // プリミティブ種類
- public uint kind;
+ public int updateIndex;
+ public int workerCount;
+ public int frameIndex; // 0 ~ (Define.System.SelfCollisionIntersectDiv-1)
// team
[Unity.Collections.ReadOnly]
+ public NativeList batchSelfTeamList;
+ [Unity.Collections.ReadOnly]
public NativeArray teamDataArray;
+ // self collision
+ [Unity.Collections.ReadOnly]
+ public NativeArray primitiveArrayB;
+ [Unity.Collections.ReadOnly]
+ public NativeArray uniformGridStartCountBuffer;
+
+ // buffer
+ [NativeDisableParallelForRestriction]
+ public NativeQueue.ParallelWriter intersectQueue;
+
+ // 1チーム
+ public void Execute(int index)
+ {
+ // 各ベースポインタ
+ TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr();
+
+ // チームインデックス
+ int localIndex = index / workerCount;
+ int teamId = batchSelfTeamList[localIndex];
+ ref var tdata = ref *(teamPt + teamId);
+ if (updateIndex >= tdata.updateCount)
+ return;
+ if (tdata.updateCount == 0)
+ return;
+ if (tdata.IsProcess == false)
+ return;
+ if (tdata.ParticleCount == 0)
+ return;
+
+ int workerIndex = index % workerCount;
+
+ // ■Edge-Triangle接触バッファ作成
+ // セルフコリジョン
+ if (tdata.flag.IsSet(TeamManager.Flag_Self_EdgeTriangleIntersect))
+ {
+ DetectionIntersect(
+ workerCount,
+ workerIndex,
+ frameIndex,
+ // edge
+ teamId,
+ ref tdata,
+ KindEdge,
+ // triangle
+ teamId,
+ ref tdata,
+ KindTriangle,
+ // self collision
+ ref primitiveArrayB,
+ ref uniformGridStartCountBuffer,
+ // intersect
+ ref intersectQueue
+ );
+ }
+
+ // 相互コリジョン
+ if (tdata.syncTeamId > 0)
+ {
+ ref var stdata = ref *(teamPt + tdata.syncTeamId);
+ if (tdata.flag.IsSet(TeamManager.Flag_Sync_EdgeTriangleIntersect))
+ {
+ DetectionIntersect(
+ workerCount,
+ workerIndex,
+ frameIndex,
+ // edge
+ teamId,
+ ref tdata,
+ KindEdge,
+ // triangle
+ tdata.syncTeamId,
+ ref stdata,
+ KindTriangle,
+ // self collision
+ ref primitiveArrayB,
+ ref uniformGridStartCountBuffer,
+ // intersect
+ ref intersectQueue
+ );
+ }
+ if (tdata.flag.IsSet(TeamManager.Flag_Sync_TriangleEdgeIntersect))
+ {
+ DetectionIntersect(
+ workerCount,
+ workerIndex,
+ frameIndex,
+ // triangle
+ teamId,
+ ref tdata,
+ KindTriangle,
+ // edge
+ tdata.syncTeamId,
+ ref stdata,
+ KindEdge,
+ // self collision
+ ref primitiveArrayB,
+ ref uniformGridStartCountBuffer,
+ // intersect
+ ref intersectQueue
+ );
+ }
+ }
+ //Debug.Log($"Detection intersect. team:{teamId}, Count:{writeCount}");
+ }
+ }
+
+ unsafe static void DetectionIntersect(
+ int workerCount,
+ int workerIndex,
+ // 0 ~ (Define.System.SelfCollisionIntersectDiv-1)
+ int frameIndex,
+ // my
+ int myTeamId,
+ ref TeamManager.TeamData myTeam,
+ uint myKind,
+ // target
+ int targetTeamId,
+ ref TeamManager.TeamData targetTeam,
+ uint targetKind,
+ // self collision
+ ref NativeArray primitiveArrayB,
+ ref NativeArray uniformGridStartCountBuffer,
+ // intersect buffer
+ ref NativeQueue.ParallelWriter intersectQueue
+ )
+ {
+ Primitive* pt = (Primitive*)primitiveArrayB.GetUnsafeReadOnlyPtr();
+ GridInfo* gt = (GridInfo*)uniformGridStartCountBuffer.GetUnsafeReadOnlyPtr();
+
+ // 参照元
+ DataChunk myPriChunk = myKind == KindPoint ? myTeam.selfPointChunk : (myKind == KindEdge ? myTeam.selfEdgeChunk : myTeam.selfTriangleChunk);
+ if (myPriChunk.IsValid == false)
+ return;
+
+ // 対象
+ DataChunk tarPriChunk = targetKind == KindPoint ? targetTeam.selfPointChunk : (targetKind == KindEdge ? targetTeam.selfEdgeChunk : targetTeam.selfTriangleChunk);
+ if (tarPriChunk.IsValid == false)
+ return;
+ int gridBufferStart = tarPriChunk.startIndex;
+ int gridBufferIndex = gridBufferStart;
+ int gridBufferCount = 0;
+ switch (targetKind)
+ {
+ case KindPoint:
+ gridBufferCount = targetTeam.selfPointGridCount;
+ break;
+ case KindEdge:
+ gridBufferCount = targetTeam.selfEdgeGridCount;
+ break;
+ case KindTriangle:
+ gridBufferCount = targetTeam.selfTriangleGridCount;
+ break;
+ }
+ float maxPrimitiveSize = targetTeam.selfMaxPrimitiveSize;
+ float gridSize = targetTeam.selfGridSize;
+
+ // 初回の交差判定はグリッドサイズ更新前に到達するので除外する
+ if (maxPrimitiveSize <= Define.System.Epsilon || gridSize <= Define.System.Epsilon)
+ return;
+
+ //Debug.Log($"edgeTeamId:{edgeTeamId}, triangleTeamId:{triangleTeamId}, gridBufferStart:{gridBufferStart}, gridBufferIndex:{gridBufferIndex}, gridBufferCount:{gridBufferCount}");
+ //Debug.Log($"edgeTeamId:{edgeTeamId}, maxPrimitiveSize:{maxPrimitiveSize}, gridSize:{gridSize}");
+
+ // プリミティブの接続判定
+ bool connectionCheck = myTeamId == targetTeamId;
+
+ // 格納自の入れ替え
+ bool primitiveFlip = myKind != KindEdge;
+
+ // 検索範囲
+ var chunk = MathUtility.GetWorkerChunk(myPriChunk.dataLength, workerCount, workerIndex);
+ if (chunk.IsValid == false)
+ return;
+
+ // プリミティブごと
+ GridInfo searchGridInfo = new GridInfo();
+ int priIndex = myPriChunk.startIndex + chunk.startIndex;
+ for (int i = 0; i < chunk.dataLength; i++, priIndex++)
+ {
+ if ((priIndex % Define.System.SelfCollisionIntersectDiv) != frameIndex)
+ continue;
+
+ ref var p = ref *(pt + priIndex);
+
+ // 無効判定
+ if (p.IsIgnore())
+ continue;
+
+ bool pFix = (p.flag & Flag_AllFix) != 0;
+
+ // このプリミティブの検索範囲
+ float3 areaMin = p.aabb.Min - maxPrimitiveSize * 0.5f;
+ float3 areaMax = p.aabb.Max + maxPrimitiveSize * 0.5f;
+
+ // グリッド範囲に変換する
+ int3 startGrid = GetGrid(areaMin, gridSize);
+ int3 endGrid = GetGrid(areaMax, gridSize);
+
+ // グリッド範囲を調べる
+ int3 currentGrid = startGrid;
+ bool finish = false;
+ while (finish == false)
+ {
+ // グリッド情報検索(ハッシュ値による2分探索)
+ int currentHash = currentGrid.GetHashCode();
+ searchGridInfo.hash = currentHash;
+ int infoIndex = NativeSortExtension.BinarySearch(gt + gridBufferStart, gridBufferCount, searchGridInfo);
+ if (infoIndex >= 0)
+ {
+ // このグリッドにはプリミティブが存在する
+ ref var gridInfo = ref *(gt + gridBufferStart + infoIndex);
+ int startPriIndex2 = gridInfo.start;
+ int endPriIndex2 = startPriIndex2 + gridInfo.count;
+
+ for (int priIndex2 = startPriIndex2; priIndex2 < endPriIndex2; priIndex2++)
+ {
+ ref var p2 = ref *(pt + priIndex2);
+
+ // AABB判定
+ if (p.aabb.Overlaps(p2.aabb) == false)
+ continue;
+
+ // 無効判定
+ if (p2.IsIgnore())
+ continue;
+
+ // 両方のプリミティブが完全固定ならば無効
+ if (pFix && ((p2.flag & Flag_AllFix) != 0))
+ continue;
+
+ // プリミティブ同士が接続している場合は無効
+ if (connectionCheck && p.AnyParticle(ref p2))
+ continue;
+
+ // !衝突検出!
+ // インターセクトバッファ生成
+ var intersect = new IntersectInfo()
+ {
+ edgeParticeIndices = primitiveFlip == false ? p.particleIndices.xy : p2.particleIndices.xy,
+ triangleParticleIndices = primitiveFlip == false ? p2.particleIndices : p.particleIndices,
+ };
+ intersectQueue.Enqueue(intersect);
+
+ //Debug.Log($"Intersect0! edge:{p.particleIndices.xyz}, tri:{p2.particleIndices.xyz}");
+ }
+ }
+
+ // next
+ currentGrid.x++;
+ if (currentGrid.x > endGrid.x)
+ {
+ currentGrid.x = startGrid.x;
+ currentGrid.y++;
+ if (currentGrid.y > endGrid.y)
+ {
+ currentGrid.y = startGrid.y;
+ currentGrid.z++;
+ if (currentGrid.z > endGrid.z)
+ {
+ finish = true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ [BurstCompile]
+ unsafe internal struct SelfConvertIntersectListJob : IJob
+ {
+ [Unity.Collections.ReadOnly]
+ public NativeQueue intersectQueue;
+
+ [NativeDisableParallelForRestriction]
+ public NativeList intersectList;
+
+ public void Execute()
+ {
+ intersectList.Clear();
+ if (intersectQueue.Count > 0)
+ intersectList.AddRange(intersectQueue.ToArray(Allocator.Temp));
+
+ //Debug.Log($"intersect count:{intersectList.Length}");
+ }
+ }
+
+ [BurstCompile]
+ unsafe internal struct SelfClearIntersectJob : IJobParallelFor
+ {
+ // team
+ [Unity.Collections.ReadOnly]
+ public NativeList batchSelfTeamList;
+ [Unity.Collections.ReadOnly]
+ public NativeArray teamDataArray;
+ // buffer
+ [Unity.Collections.WriteOnly]
+ [NativeDisableParallelForRestriction]
+ public NativeArray intersectFlagArray;
+
+ public void Execute(int index)
+ {
+ // 各ベースポインタ
+ TeamManager.TeamData* teamPt = (TeamManager.TeamData*)teamDataArray.GetUnsafeReadOnlyPtr();
+
+ // チームインデックス
+ int teamId = batchSelfTeamList[index];
+ ref var tdata = ref *(teamPt + teamId);
+ if (tdata.IsProcess == false)
+ return;
+ if (tdata.ParticleCount == 0)
+ return;
+
+ int pindex = tdata.particleChunk.startIndex;
+ for (int i = 0; i < tdata.particleChunk.dataLength; i++, pindex++)
+ {
+ intersectFlagArray[pindex] = 0;
+ }
+ }
+ }
+
+ [BurstCompile]
+ unsafe internal struct SelfSolverIntersectJob : IJobParallelForDefer
+ {
// particle
[Unity.Collections.ReadOnly]
public NativeArray nextPosArray;
- // constraint
- [NativeDisableParallelForRestriction]
- public NativeArray primitiveArray;
-
- // processing
+ // self collision
[Unity.Collections.ReadOnly]
- public NativeArray processingArray;
+ public NativeList intersectList;
- public void Execute(int index)
- {
- uint pack = processingArray[index];
- int teamId = DataUtility.Unpack32Hi(pack);
- int l_index = DataUtility.Unpack32Low(pack);
-
- // チームはこのステップで有効であることが保証されている
- var tdata = teamDataArray[teamId];
- if (kind == KindEdge && tdata.flag.TestAny(TeamManager.Flag_Self_EdgeTriangleIntersect, 3) == false)
- return;
- if (kind == KindTriangle && tdata.flag.TestAny(TeamManager.Flag_Self_TriangleEdgeIntersect, 3) == false)
- return;
-
- // primitive
- int pri_index = 0;
- switch (kind)
- {
- case KindPoint:
- pri_index = tdata.selfPointChunk.startIndex + l_index;
- break;
- case KindEdge:
- pri_index = tdata.selfEdgeChunk.startIndex + l_index;
- break;
- case KindTriangle:
- pri_index = tdata.selfTriangleChunk.startIndex + l_index;
- break;
- }
- var primitive = primitiveArray[pri_index];
-
- // プリミティブnextPos更新
- int ac = (int)kind + 1; // 軸の数
- for (int i = 0; i < ac; i++)
- {
- int pindex = primitive.particleIndices[i];
- primitive.nextPos[i] = nextPosArray[pindex];
- }
- primitiveArray[pri_index] = primitive;
- }
- }
-
- [BurstCompile]
- struct IntersectEdgeTriangleJob : IJobParallelForDefer
- {
- public uint mainKind;
- public int execNumber;
- public int div;
-
- // team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
-
- // constraint
- [Unity.Collections.ReadOnly]
- public NativeArray primitiveArray;
- [Unity.Collections.ReadOnly]
- public NativeArray sortAndSweepArray;
-
- // processing
- [Unity.Collections.ReadOnly]
- public NativeArray processingEdgeEdgeArray;
-
- // out
+ // buffer
+ [Unity.Collections.WriteOnly]
[NativeDisableParallelForRestriction]
public NativeArray intersectFlagArray;
- // 解決Edge/Triangleごと
+
public void Execute(int index)
{
-#if true
- // 分割実行判定
- if (index % div != execNumber)
- return;
-#endif
+ IntersectInfo* it = (IntersectInfo*)intersectList.GetUnsafeReadOnlyPtr();
- uint pack = processingEdgeEdgeArray[index];
- int teamId = DataUtility.Unpack32Hi(pack);
- int l_index = DataUtility.Unpack32Low(pack);
+ ref var intersect = ref *(it + index);
- // チームはこのステップで有効であることが保証されている
- var tdata = teamDataArray[teamId];
- if (mainKind == KindEdge && tdata.flag.TestAny(TeamManager.Flag_Self_EdgeTriangleIntersect, 3) == false)
- return;
- if (mainKind == KindTriangle && tdata.flag.TestAny(TeamManager.Flag_Self_TriangleEdgeIntersect, 3) == false)
- return;
+ // edge
+ float3 p = nextPosArray[intersect.edgeParticeIndices.x];
+ float3 q = nextPosArray[intersect.edgeParticeIndices.y];
- // メインとサブのチャンク
- bool isEdge = mainKind == KindEdge;
- var mainChunk = isEdge ? tdata.selfEdgeChunk : tdata.selfTriangleChunk;
- var subChunk = isEdge ? tdata.selfTriangleChunk : tdata.selfEdgeChunk;
-
- // メインプリミティブ情報
- int priIndex0 = mainChunk.startIndex + l_index;
- var primitive0 = primitiveArray[priIndex0];
- var sd0 = sortAndSweepArray[primitive0.sortIndex];
-
- //=============================================================
- // Self
- //=============================================================
- if (tdata.flag.IsSet(isEdge ? TeamManager.Flag_Self_EdgeTriangleIntersect : TeamManager.Flag_Self_TriangleEdgeIntersect))
- {
- SweepTest(ref primitive0, sd0, subChunk, true);
- }
-
- //=============================================================
- // Sync
- //=============================================================
- if (tdata.flag.IsSet(isEdge ? TeamManager.Flag_Sync_EdgeTriangleIntersect : TeamManager.Flag_Sync_TriangleEdgeIntersect))
- {
- var stdata = teamDataArray[tdata.syncTeamId];
- SweepTest(ref primitive0, sd0, isEdge ? stdata.selfTriangleChunk : stdata.selfEdgeChunk, false);
- }
-
- //=============================================================
- // Parent Sync
- //=============================================================
- if (tdata.flag.IsSet(isEdge ? TeamManager.Flag_PSync_EdgeTriangleIntersect : TeamManager.Flag_PSync_TriangleEdgeIntersect))
- {
- int cnt = tdata.syncParentTeamId.Length;
- for (int j = 0; j < cnt; j++)
- {
- int parentTeamId = tdata.syncParentTeamId[j];
- var stdata = teamDataArray[parentTeamId];
- if (stdata.flag.IsSet(isEdge ? TeamManager.Flag_Sync_TriangleEdgeIntersect : TeamManager.Flag_Sync_EdgeTriangleIntersect))
- {
- SweepTest(ref primitive0, sd0, isEdge ? stdata.selfTriangleChunk : stdata.selfEdgeChunk, false);
- }
- }
- }
- }
-
- void SweepTest(ref Primitive primitive0, in SortData sd0, in DataChunk subChunk, bool connectionCheck)
- {
- // スイープ
- int sortIndex = BinarySearchSortAndlSweep(ref sortAndSweepArray, sd0, subChunk);
- float end = sd0.firstMinMax.y;
- int endIndex = subChunk.startIndex + subChunk.dataLength;
- while (sortIndex < endIndex)
- {
- var sd1 = sortAndSweepArray[sortIndex];
- sortIndex++;
-
- // first
- if (sd1.firstMinMax.x <= end)
- {
- // second
- if (sd1.secondMinMax.y < sd0.secondMinMax.x || sd1.secondMinMax.x > sd0.secondMinMax.y)
- continue;
-
- // third
- if (sd1.thirdMinMax.y < sd0.thirdMinMax.x || sd1.thirdMinMax.x > sd0.thirdMinMax.y)
- continue;
-
- // この時点で両方のAABBは衝突している
- var primitive1 = primitiveArray[sd1.primitiveIndex];
-
- // プリミティブ同士が接続している場合は無効
- if (connectionCheck && primitive0.AnyParticle(primitive1))
- continue;
-
- // 両方のプリミティブが完全固定ならば無効
- if ((primitive0.flagAndTeamId & Flag_AllFix) != 0 && (primitive1.flagAndTeamId & Flag_AllFix) != 0)
- continue;
-
- // 交差判定
- if (mainKind == KindEdge)
- {
- IntersectTest(ref primitive0, ref primitive1);
- }
- else
- {
- IntersectTest(ref primitive1, ref primitive0);
- }
- }
- else
- break;
- }
- }
-
- void IntersectTest(ref Primitive epri, ref Primitive tpri)
- {
- //Debug.Log($"IntersectTest. edge:{epri.particleIndices.xy}, tri:{tpri.particleIndices.xyz}");
+ // triangle
+ float3 a = nextPosArray[intersect.triangleParticleIndices.x];
+ float3 b = nextPosArray[intersect.triangleParticleIndices.y];
+ float3 c = nextPosArray[intersect.triangleParticleIndices.z];
+ // Intersect test
// 線分とトライアングルの交差判定
- var p = epri.nextPos.c0;
- var q = epri.nextPos.c1;
var qp = p - q;
- float3 a = tpri.nextPos.c0;
- float3 b = tpri.nextPos.c1;
- float3 c = tpri.nextPos.c2;
var ac = c - a;
var ab = b - a;
float3 n = math.cross(ab, ac);
@@ -2529,7 +2282,8 @@ namespace MagicaCloth2
// 法線裏側からの侵入に対応
if (d < 0.0f)
{
- p = epri.nextPos.c1;
+ //p = epri.nextPos.c1;
+ p = q;
qp = -qp;
d = -d;
}
@@ -2549,15 +2303,14 @@ namespace MagicaCloth2
if (w < 0.0f || (v + w) > d)
return;
- // 交差
- // EdgeとTriangleにフラグを立てる
- intersectFlagArray[epri.particleIndices.x] = 1;
- intersectFlagArray[epri.particleIndices.y] = 1;
- intersectFlagArray[tpri.particleIndices.x] = 1;
- intersectFlagArray[tpri.particleIndices.y] = 1;
- intersectFlagArray[tpri.particleIndices.z] = 1;
+ // !交差!
+ // Edgeにフラグを立てる
+ intersectFlagArray[intersect.edgeParticeIndices.x] = 1;
+ intersectFlagArray[intersect.edgeParticeIndices.y] = 1;
- //Debug.Log($"Intersect.[{execNumber}] Edge:{epri.particleIndices.xy}, Tri:{tpri.particleIndices.xyz}");
+ // Triangleにはフラグは立てない
+
+ //Debug.Log($"Intersect! edge:{p0.particleIndices.xyz}, tri:{p1.particleIndices.xyz}");
}
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs.meta
index 6ba80d67..97fc4b52 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SelfCollisionConstraint.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs
index 186e8eef..39968c8c 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs
@@ -3,7 +3,6 @@
// https://magicasoft.jp
using System;
-using Unity.Jobs;
using UnityEngine;
namespace MagicaCloth2
@@ -127,11 +126,5 @@ namespace MagicaCloth2
public void Dispose()
{
}
-
- //=========================================================================================
- unsafe internal JobHandle SolverConstraint(JobHandle jobHandle)
- {
- return jobHandle;
- }
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs.meta
index 7a1ec06a..0c9a1ac1 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/SpringConstraint.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs
index 6d20503d..46840a4a 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs
@@ -2,9 +2,7 @@
// Copyright (c) 2023 MagicaSoft.
// https://magicasoft.jp
using System;
-using Unity.Burst;
using Unity.Collections;
-using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
@@ -32,7 +30,7 @@ namespace MagicaCloth2
public SerializeData()
{
- distanceCompression = 0.9f;
+ distanceCompression = 0.4f;
}
public void DataValidate()
@@ -85,102 +83,41 @@ namespace MagicaCloth2
}
//=========================================================================================
- ///
- /// 制約の解決
- ///
- ///
- ///
- ///
- unsafe internal JobHandle SolverConstraint(JobHandle jobHandle)
- {
- var tm = MagicaManager.Team;
- var sm = MagicaManager.Simulation;
- var vm = MagicaManager.VMesh;
-
- var job = new TethreConstraintJob()
- {
- stepParticleIndexArray = sm.processingStepParticle.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
- centerDataArray = tm.centerDataArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- vertexDepths = vm.vertexDepths.GetNativeArray(),
- vertexRootIndices = vm.vertexRootIndices.GetNativeArray(),
-
- teamIdArray = sm.teamIdArray.GetNativeArray(),
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- velocityPosArray = sm.velocityPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
-
- stepBasicPositionBuffer = sm.stepBasicPositionBuffer,
- };
- jobHandle = job.Schedule(sm.processingStepParticle.GetJobSchedulePtr(), 32, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct TethreConstraintJob : IJobParallelForDefer
- {
- [Unity.Collections.ReadOnly]
- public NativeArray stepParticleIndexArray;
-
+ // Solver
+ //=========================================================================================
+ internal static void SolverConstraint(
+ DataChunk chunk,
// team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
- [Unity.Collections.ReadOnly]
- public NativeArray centerDataArray;
-
+ ref TeamManager.TeamData tdata,
+ ref ClothParameters param,
+ ref InertiaConstraint.CenterData cdata,
// vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexDepths;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexRootIndices;
-
+ ref NativeArray attributes,
+ ref NativeArray vertexDepths,
+ ref NativeArray vertexRootIndices,
// particle
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
- [NativeDisableParallelForRestriction]
- public NativeArray velocityPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray frictionArray;
-
+ ref NativeArray nextPosArray,
+ ref NativeArray velocityPosArray,
+ ref NativeArray frictionArray,
// buffer
- [Unity.Collections.ReadOnly]
- public NativeArray stepBasicPositionBuffer;
-
- // パーティクルごと
- public void Execute(int index)
+ ref NativeArray stepBasicPositionBuffer
+ )
+ {
+ int p_start = tdata.particleChunk.startIndex;
+ //int pindex = p_start;
+ int pindex = p_start + chunk.startIndex;
+ //int vindex = tdata.proxyCommonChunk.startIndex;
+ int vindex = tdata.proxyCommonChunk.startIndex + chunk.startIndex;
+ //for (int k = 0; k < tdata.particleChunk.dataLength; k++, pindex++, vindex++)
+ for (int k = 0; k < chunk.dataLength; k++, pindex++, vindex++)
{
- // pindexのチームは有効であることが保証されている
- int pindex = stepParticleIndexArray[index];
-
- int teamId = teamIdArray[pindex];
- var tdata = teamDataArray[teamId];
- var param = parameterArray[teamId].tetherConstraint;
- //if (param.stiffness < 1e-06f)
- // return;
-
- int p_start = tdata.particleChunk.startIndex;
- int l_index = pindex - p_start;
- int v_start = tdata.proxyCommonChunk.startIndex;
- int vindex = v_start + l_index;
-
var attr = attributes[vindex];
if (attr.IsMove() == false)
- return;
+ continue;
int rootIndex = vertexRootIndices[vindex];
if (rootIndex < 0)
- return;
+ continue;
//Debug.Log($"Tether [{pindex}] root:{rootIndex + p_start}");
@@ -198,7 +135,7 @@ namespace MagicaCloth2
// 距離がほぼ0ならば処理をスキップする(エラーの回避)
if (distance < Define.System.Epsilon)
- return;
+ continue;
// 復元距離
// フラグにより初期姿勢かアニメーション後姿勢かを切り替える
@@ -210,7 +147,7 @@ namespace MagicaCloth2
// 初期位置がまったく同じ状況を考慮
if (calcDistance == 0.0f)
- return;
+ continue;
// 現在の伸縮割合
//Develop.Assert(calcDistance > 0.0f);
@@ -220,8 +157,8 @@ namespace MagicaCloth2
float dist = 0;
float stiffness;
float attn;
- float compressionLimit = 1.0f - param.compressionLimit;
- float stretchLimit = 1.0f + param.stretchLimit;
+ float compressionLimit = 1.0f - param.tetherConstraint.compressionLimit;
+ float stretchLimit = 1.0f + param.tetherConstraint.stretchLimit;
//float widthRatio = math.max(param.stiffnessWidth, 0.001f); // 0.2?
//float widthRatio = 0.1f; // 0.2?
if (ratio < compressionLimit)
@@ -243,7 +180,7 @@ namespace MagicaCloth2
attn = Define.System.TetherStretchVelocityAttenuation;
}
else
- return;
+ continue;
// 移動量
float3 add = (v / distance) * (dist * stiffness);
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs.meta
index 4e1dc9e2..72152c36 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TetherConstraint.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs
index b7211c41..4a498f1b 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs
@@ -4,9 +4,8 @@
using System;
using System.Collections.Generic;
using System.Text;
-using Unity.Burst;
using Unity.Collections;
-using Unity.Jobs;
+using Unity.Collections.LowLevel.Unsafe;
using Unity.Mathematics;
using UnityEngine;
@@ -17,6 +16,11 @@ namespace MagicaCloth2
///
public class TriangleBendingConstraint : IDisposable
{
+ ///
+ /// ボリュームとして処理する判定フラグ
+ ///
+ const sbyte VOLUME_SIGN = 100;
+
public enum Method
{
None = 0,
@@ -29,7 +33,7 @@ namespace MagicaCloth2
///
/// 方向性ありの2面角曲げ制約
- /// 初期姿勢を保た持つように復元する
+ /// 初期姿勢を保つように復元する
///
DirectionDihedralAngle = 2,
}
@@ -73,16 +77,17 @@ namespace MagicaCloth2
public void Convert(SerializeData sdata)
{
- //method = sdata.method;
// モードはDirectionDihedralAngleに固定する
method = sdata.stiffness > Define.System.Epsilon ? Method.DirectionDihedralAngle : Method.None;
+ //method = sdata.stiffness > Define.System.Epsilon ? Method.DihedralAngle : Method.None;
stiffness = sdata.stiffness;
}
}
//=========================================================================================
- internal class ConstraintData : IValid
+ [System.Serializable]
+ public class ConstraintData : IValid
{
public ResultCode result;
public ulong[] trianglePairArray;
@@ -116,29 +121,16 @@ namespace MagicaCloth2
public ExNativeArray restAngleOrVolumeArray;
///
- /// トライアングルペアごとの復元方向もしくはボリューム判定(100=このペアはボリュームである)
+ /// トライアングルペアごとの復元方向もしくはボリューム判定(VOLUME_SIGN(100)=このペアはボリュームである)
///
public ExNativeArray signOrVolumeArray;
- ///
- /// トライアングルペアごとの結果書き込みローカルインデックス
- /// 4つのbyteを1つのuintに結合したもの
- ///
- public ExNativeArray writeDataArray;
+ //public int DataCount => trianglePairArray?.Count ?? 0;
///
- /// 頂点ごとの書き込みバッファの数と開始インデックス
- /// (上位10bit = カウンタ, 下位22bit = 開始インデックス)
+ /// ボリューム計算の浮動小数点誤差を回避するための倍数
///
- public ExNativeArray writeIndexArray;
-
- ///
- /// 頂点ごとの書き込みバッファ(集計用)
- /// writeIndexArrayに従う
- ///
- public ExNativeArray writeBuffer;
-
- public int DataCount => trianglePairArray?.Count ?? 0;
+ const float VolumeScale = 1000.0f;
//=========================================================================================
public TriangleBendingConstraint()
@@ -146,9 +138,6 @@ namespace MagicaCloth2
trianglePairArray = new ExNativeArray(0, true);
restAngleOrVolumeArray = new ExNativeArray(0, true);
signOrVolumeArray = new ExNativeArray(0, true);
- writeDataArray = new ExNativeArray(0, true);
- writeIndexArray = new ExNativeArray(0, true);
- writeBuffer = new ExNativeArray(0, true);
}
public void Dispose()
@@ -156,9 +145,6 @@ namespace MagicaCloth2
trianglePairArray?.Dispose();
restAngleOrVolumeArray?.Dispose();
signOrVolumeArray?.Dispose();
- writeDataArray?.Dispose();
- writeIndexArray?.Dispose();
- writeBuffer?.Dispose();
trianglePairArray = null;
restAngleOrVolumeArray = null;
@@ -172,9 +158,6 @@ namespace MagicaCloth2
sb.AppendLine($" -trianglePairArray:{trianglePairArray.ToSummary()}");
sb.AppendLine($" -restAngleOrVolumeArray:{restAngleOrVolumeArray.ToSummary()}");
sb.AppendLine($" -signOrVolumeArray:{signOrVolumeArray.ToSummary()}");
- sb.AppendLine($" -writeDataArray:{writeDataArray.ToSummary()}");
- sb.AppendLine($" -writeIndexArray:{writeIndexArray.ToSummary()}");
- sb.AppendLine($" -writeBuffer:{writeBuffer.ToSummary()}");
return sb.ToString();
}
@@ -186,7 +169,7 @@ namespace MagicaCloth2
///
///
///
- internal static ConstraintData CreateData(VirtualMesh proxyMesh, in ClothParameters parameters)
+ public static ConstraintData CreateData(VirtualMesh proxyMesh, in ClothParameters parameters)
{
var constraintData = new ConstraintData();
@@ -223,7 +206,7 @@ namespace MagicaCloth2
if (proxyMesh.edgeToTriangles.ContainsKey(edge) == false)
continue;
- var triangles = proxyMesh.edgeToTriangles.ToFixedList128Bytes(edge);
+ var triangles = proxyMesh.edgeToTriangles.MC2ToFixedList128Bytes(edge);
int tcnt = triangles.Length;
// トライアングルの組み合わせ
@@ -276,6 +259,7 @@ namespace MagicaCloth2
trianglePairList.Add(pair);
restAngleOrVolumeList.Add(restData);
signOrVolumeList.Add(signFlag);
+ //Debug.Log($"rest angle:{math.degrees(restData)}, signFlag:{signFlag}");
uint writeData = DataUtility.Pack32(
multiBuilder.CountValuesForKey(vtx.x),
@@ -320,7 +304,7 @@ namespace MagicaCloth2
volumeCount++;
- //Develop.DebugLog($"Volume Pair. edge:{edge}, tri:({tri0},{tri1}) restAngle:{degAngle}");
+ //Develop.DebugLog($"Volume Pair. edge:{edge}, tri:({tri0},{tri1}) restAngle:{degAngle}, restData:{restData}, signFlag:{signFlag}");
}
}
//if (math.all(tri0 - 243) == false || math.all(tri1 - 243) == false)
@@ -357,13 +341,15 @@ namespace MagicaCloth2
static void InitVolume(VirtualMesh proxyMesh, int v0, int v1, int v2, int v3, out float volumeRest, out sbyte signFlag)
{
// 0/1が対角点,2/3が共通辺
- float3 pos0 = proxyMesh.localPositions[v0];
- float3 pos1 = proxyMesh.localPositions[v1];
- float3 pos2 = proxyMesh.localPositions[v2];
- float3 pos3 = proxyMesh.localPositions[v3];
+ // ここは実行時とボリューム値を合わせるためワールド座標で計算する必要がある。
+ float3 pos0 = MathUtility.TransformPoint(proxyMesh.localPositions[v0], proxyMesh.initLocalToWorld);
+ float3 pos1 = MathUtility.TransformPoint(proxyMesh.localPositions[v1], proxyMesh.initLocalToWorld);
+ float3 pos2 = MathUtility.TransformPoint(proxyMesh.localPositions[v2], proxyMesh.initLocalToWorld);
+ float3 pos3 = MathUtility.TransformPoint(proxyMesh.localPositions[v3], proxyMesh.initLocalToWorld);
volumeRest = (1.0f / 6.0f) * math.dot(math.cross(pos1 - pos0, pos2 - pos0), pos3 - pos0);
- signFlag = 100; // Volume
+ volumeRest *= VolumeScale; // 浮動小数点演算誤差回避
+ signFlag = VOLUME_SIGN; // Volume
}
static void InitDihedralAngle(VirtualMesh proxyMesh, int v0, int v1, int v2, int v3, out float restAngle, out sbyte signFlag)
@@ -409,11 +395,6 @@ namespace MagicaCloth2
tdata.bendingPairChunk = trianglePairArray.AddRange(cdata.trianglePairArray);
restAngleOrVolumeArray.AddRange(cdata.restAngleOrVolumeArray);
signOrVolumeArray.AddRange(cdata.signOrVolumeArray);
- writeDataArray.AddRange(cdata.writeDataArray);
-
- // write buffer
- tdata.bendingWriteIndexChunk = writeIndexArray.AddRange(cdata.writeIndexArray);
- tdata.bendingBufferChunk = writeBuffer.AddRange(cdata.writeBufferCount);
}
}
@@ -430,159 +411,78 @@ namespace MagicaCloth2
trianglePairArray.Remove(tdata.bendingPairChunk);
restAngleOrVolumeArray.Remove(tdata.bendingPairChunk);
signOrVolumeArray.Remove(tdata.bendingPairChunk);
- writeDataArray.Remove(tdata.bendingPairChunk);
-
- // write buffer
- writeIndexArray.Remove(tdata.bendingWriteIndexChunk);
- writeBuffer.Remove(tdata.bendingBufferChunk);
tdata.bendingPairChunk.Clear();
- tdata.bendingWriteIndexChunk.Clear();
- tdata.bendingBufferChunk.Clear();
}
}
//=========================================================================================
- ///
- /// 制約の解決
- ///
- ///
- ///
- unsafe internal JobHandle SolverConstraint(JobHandle jobHandle)
- {
- var tm = MagicaManager.Team;
- var sm = MagicaManager.Simulation;
- var vm = MagicaManager.VMesh;
-
- if (DataCount > 0)
- {
- var triangleBendingJob = new TriangleBendingJob()
- {
- simulationPower = MagicaManager.Time.SimulationPower,
-
- stepTriangleBendIndexArray = sm.processingStepTriangleBending.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- depthArray = vm.vertexDepths.GetNativeArray(),
-
- nextPosArray = sm.nextPosArray.GetNativeArray(),
- frictionArray = sm.frictionArray.GetNativeArray(),
-
- trianglePairArray = trianglePairArray.GetNativeArray(),
- restAngleOrVolumeArray = restAngleOrVolumeArray.GetNativeArray(),
- signOrVolumeArray = signOrVolumeArray.GetNativeArray(),
-
- writeDataArray = writeDataArray.GetNativeArray(),
- writeIndexArray = writeIndexArray.GetNativeArray(),
- writeBuffer = writeBuffer.GetNativeArray(),
- };
- jobHandle = triangleBendingJob.Schedule(sm.processingStepTriangleBending.GetJobSchedulePtr(), 16, jobHandle);
-
- // 集計(速度影響はなし)
- var aggregateJob = new SolveAggregateBufferJob()
- {
- stepParticleIndexArray = sm.processingStepParticle.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
-
- teamIdArray = sm.teamIdArray.GetNativeArray(),
- nextPosArray = sm.nextPosArray.GetNativeArray(),
-
- writeIndexArray = writeIndexArray.GetNativeArray(),
- writeBuffer = writeBuffer.GetNativeArray(),
- };
- jobHandle = aggregateJob.Schedule(sm.processingStepParticle.GetJobSchedulePtr(), 16, jobHandle);
- }
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct TriangleBendingJob : IJobParallelForDefer
- {
- public float4 simulationPower;
-
- [Unity.Collections.ReadOnly]
- public NativeArray stepTriangleBendIndexArray;
-
+ // Solver
+ //=========================================================================================
+ internal unsafe static void SolverConstraint(
+ DataChunk chunk,
+ in float4 simulationPower,
// team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
-
+ ref TeamManager.TeamData tdata,
+ ref ClothParameters param,
// vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray depthArray;
-
-
+ ref NativeArray attributes,
+ ref NativeArray depthArray,
// particle
- [Unity.Collections.ReadOnly]
- public NativeArray nextPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray frictionArray;
-
+ ref NativeArray nextPosArray,
+ ref NativeArray frictionArray,
// constraints
- [Unity.Collections.ReadOnly]
- public NativeArray trianglePairArray;
- [Unity.Collections.ReadOnly]
- public NativeArray restAngleOrVolumeArray;
- [Unity.Collections.ReadOnly]
- public NativeArray signOrVolumeArray;
- [Unity.Collections.ReadOnly]
- public NativeArray writeDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray writeIndexArray;
+ ref NativeArray trianglePairArray,
+ ref NativeArray restAngleOrVolumeArray,
+ ref NativeArray signOrVolumeArray,
+ // buffer2
+ ref NativeArray tempVectorBufferA,
+ ref NativeArray tempCountBuffer
+ )
+ {
+ if (param.triangleBendingConstraint.method == Method.None)
+ return;
- // output
- [NativeDisableParallelForRestriction]
- public NativeArray writeBuffer;
+ if (tdata.bendingPairChunk.IsValid == false)
+ return;
- // ベンドトライアングルペアごと
- public void Execute(int index)
+ // 剛性
+ float stiffness = param.triangleBendingConstraint.stiffness;
+ if (stiffness < 1e-06f)
+ return;
+ stiffness = math.saturate(stiffness * simulationPower.y);
+
+ int p_start = tdata.particleChunk.startIndex;
+ int v_start = tdata.proxyCommonChunk.startIndex;
+ int pindex;
+ int vindex;
+
+ int* sumPt = (int*)tempVectorBufferA.GetUnsafePtr();
+ int* cntPt = (int*)tempCountBuffer.GetUnsafePtr();
+
+ // ■計算
+ // ベンドペアごと
+ //int pairIndex = tdata.bendingPairChunk.startIndex;
+ int pairIndex = tdata.bendingPairChunk.startIndex + chunk.startIndex;
+ //for (int k = 0; k < tdata.bendingPairChunk.dataLength; k++, pairIndex++)
+ for (int k = 0; k < chunk.dataLength; k++, pairIndex++)
{
- // インデックスのチームは有効であることが保証されている
- //int pairIndex = stepTriangleBendIndexArray[index];
- //int teamId = trianglePairTeamIdArray[pairIndex];
- uint pack = (uint)stepTriangleBendIndexArray[index];
- int pairIndex = DataUtility.Unpack12_20Low(pack);
- int teamId = DataUtility.Unpack12_20Hi(pack);
- var tdata = teamDataArray[teamId];
- var parameter = parameterArray[teamId].triangleBendingConstraint;
- if (parameter.method == Method.None)
- return;
-
- // 剛性
- float stiffness = parameter.stiffness;
- if (stiffness < 1e-06f)
- return;
- stiffness = math.saturate(stiffness * simulationPower.y);
-
-
- int p_start = tdata.particleChunk.startIndex;
- int v_start = tdata.proxyCommonChunk.startIndex;
-
// トライアングルペア
var pairData = trianglePairArray[pairIndex];
int4 vertices = DataUtility.Unpack64(pairData);
//Debug.Log(vertices);
+ int4 pindex4 = vertices + p_start;
+ int4 vindex4 = vertices + v_start;
+
// 状態
float3x4 nextPosBuffer = 0;
float3x4 addPosBuffer = 0;
float4 invMassBuffer = 1;
- //int4 fixedBuffer = 0;
for (int i = 0; i < 4; i++)
{
- int pindex = p_start + vertices[i];
- int vindex = v_start + vertices[i];
+ pindex = pindex4[i];
+ vindex = vindex4[i];
nextPosBuffer[i] = nextPosArray[pindex];
float friction = frictionArray[pindex];
float depth = depthArray[vindex];
@@ -598,220 +498,241 @@ namespace MagicaCloth2
// メソッドごとの解決
bool result = false;
- if (signOrVolume == 100)
+ if (signOrVolume == VOLUME_SIGN)
{
// Volume
- result = Volume(nextPosBuffer, invMassBuffer, restAngle, stiffness, ref addPosBuffer);
+ float volumeRest = restAngle * tdata.scaleRatio; // スケール倍率
+
+ // マイナススケール
+ volumeRest *= tdata.negativeScaleSign;
+
+ result = CalcVolume(nextPosBuffer, invMassBuffer, volumeRest, stiffness, ref addPosBuffer);
}
else
{
// Triangle Bending
- float sign = signOrVolume < 0 ? -1 : 1;
- if (parameter.method == Method.DihedralAngle)
+ if (param.triangleBendingConstraint.method == Method.DihedralAngle)
{
- // 二面角
- result = DihedralAngle(0, nextPosBuffer, invMassBuffer, restAngle, stiffness, ref addPosBuffer);
+ // 方向性なし二面角
+ result = CalcDihedralAngle(0, nextPosBuffer, invMassBuffer, restAngle, stiffness, ref addPosBuffer);
}
- else if (parameter.method == Method.DirectionDihedralAngle)
+ else if (param.triangleBendingConstraint.method == Method.DirectionDihedralAngle)
{
- // 方向性二面角
+ // 方向性あり二面角
+ float sign = signOrVolume < 0 ? -1 : 1;
restAngle *= sign;
- result = DihedralAngle(sign, nextPosBuffer, invMassBuffer, restAngle, stiffness, ref addPosBuffer);
+
+ // マイナススケール
+ restAngle *= tdata.negativeScaleSign;
+
+ result = CalcDihedralAngle(sign, nextPosBuffer, invMassBuffer, restAngle, stiffness, ref addPosBuffer);
}
}
// 集計バッファへ格納
if (result)
{
- int4 writeData = DataUtility.Unpack32(writeDataArray[dataIndex]);
- int indexStart = tdata.bendingWriteIndexChunk.startIndex;
- int bufferStart = tdata.bendingBufferChunk.startIndex;
for (int i = 0; i < 4; i++)
{
- int l_vindex = vertices[i];
- int start = DataUtility.Unpack12_20Low(writeIndexArray[indexStart + l_vindex]);
- int bufferIndex = bufferStart + start + writeData[i];
- writeBuffer[bufferIndex] = addPosBuffer[i];
+ pindex = pindex4[i];
+ InterlockUtility.AddFloat3(pindex, addPosBuffer[i], cntPt, sumPt);
}
}
}
+ }
- bool Volume(in float3x4 nextPosBuffer, in float4 invMassBuffer, float volumeRest, float stiffness, ref float3x4 addPosBuffer)
+ internal unsafe static void SumConstraint(
+ DataChunk chunk,
+ // team
+ ref TeamManager.TeamData tdata,
+ ref ClothParameters param,
+ // vmesh
+ ref NativeArray attributes,
+ // particle
+ ref NativeArray nextPosArray,
+ // buffer2
+ ref NativeArray tempVectorBufferA,
+ ref NativeArray tempCountBuffer
+ )
+ {
+ if (param.triangleBendingConstraint.method == Method.None)
+ return;
+
+ if (tdata.bendingPairChunk.IsValid == false)
+ return;
+
+ // 剛性
+ float stiffness = param.triangleBendingConstraint.stiffness;
+ if (stiffness < 1e-06f)
+ return;
+
+ int p_start = tdata.particleChunk.startIndex;
+ int v_start = tdata.proxyCommonChunk.startIndex;
+
+ int* sumPt = (int*)tempVectorBufferA.GetUnsafePtr();
+ int* cntPt = (int*)tempCountBuffer.GetUnsafePtr();
+
+ // ■集計
+ // パーティクルごと
+ int pindex = p_start + chunk.startIndex;
+ int vindex = v_start + chunk.startIndex;
+ //for (int k = 0; k < tdata.particleChunk.dataLength; k++, pindex++, vindex++)
+ for (int k = 0; k < chunk.dataLength; k++, pindex++, vindex++)
{
- float3 nextPos0 = nextPosBuffer[0];
- float3 nextPos1 = nextPosBuffer[1];
- float3 nextPos2 = nextPosBuffer[2];
- float3 nextPos3 = nextPosBuffer[3];
-
- float invMass0 = invMassBuffer[0];
- float invMass1 = invMassBuffer[1];
- float invMass2 = invMassBuffer[2];
- float invMass3 = invMassBuffer[3];
-
- float volume = (1.0f / 6.0f) * math.dot(math.cross(nextPos1 - nextPos0, nextPos2 - nextPos0), nextPos3 - nextPos0);
-
- float3 grad0 = math.cross(nextPos1 - nextPos2, nextPos3 - nextPos2);
- float3 grad1 = math.cross(nextPos2 - nextPos0, nextPos3 - nextPos0);
- float3 grad2 = math.cross(nextPos0 - nextPos1, nextPos3 - nextPos1);
- float3 grad3 = math.cross(nextPos1 - nextPos0, nextPos2 - nextPos0);
-
- float lambda =
- invMass0 * math.lengthsq(grad0) +
- invMass1 * math.lengthsq(grad1) +
- invMass2 * math.lengthsq(grad2) +
- invMass3 * math.lengthsq(grad3);
-
- if (math.abs(lambda) < 1e-06f)
- return false;
-
- lambda = stiffness * (volume - volumeRest) / lambda;
-
- addPosBuffer[0] = -lambda * invMass0 * grad0;
- addPosBuffer[1] = -lambda * invMass1 * grad1;
- addPosBuffer[2] = -lambda * invMass2 * grad2;
- addPosBuffer[3] = -lambda * invMass3 * grad3;
-
- return true;
- }
-
- bool DihedralAngle(float sign, in float3x4 nextPosBuffer, in float4 invMassBuffer, float restAngle, float stiffness, ref float3x4 addPosBuffer)
- {
- float3 nextPos0 = nextPosBuffer[0];
- float3 nextPos1 = nextPosBuffer[1];
- float3 nextPos2 = nextPosBuffer[2];
- float3 nextPos3 = nextPosBuffer[3];
-
- float invMass0 = invMassBuffer[0];
- float invMass1 = invMassBuffer[1];
- float invMass2 = invMassBuffer[2];
- float invMass3 = invMassBuffer[3];
-
- float3 e = nextPos3 - nextPos2;
- float elen = math.length(e);
- if (elen < 1e-08f)
- return false;
-
- float invElen = 1.0f / elen;
-
- float3 n1 = math.cross(nextPos2 - nextPos0, nextPos3 - nextPos0);
- float3 n2 = math.cross(nextPos3 - nextPos1, nextPos2 - nextPos1);
- float n1_lengsq = math.lengthsq(n1);
- float n2_lengsq = math.lengthsq(n2);
-
- // 稀に発生する長さ0に対処
- if (n1_lengsq == 0.0f || n2_lengsq == 0.0f)
- return false;
- //Develop.Assert(n1_lengsq > 0.0f);
- //Develop.Assert(n2_lengsq > 0.0f);
- n1 /= n1_lengsq;
- n2 /= n2_lengsq;
-
- float3 d0 = elen * n1;
- float3 d1 = elen * n2;
- float3 d2 = math.dot(nextPos0 - nextPos3, e) * invElen * n1 + math.dot(nextPos1 - nextPos3, e) * invElen * n2;
- float3 d3 = math.dot(nextPos2 - nextPos0, e) * invElen * n1 + math.dot(nextPos2 - nextPos1, e) * invElen * n2;
-
- n1 = math.normalize(n1);
- n2 = math.normalize(n2);
- float dot = math.dot(n1, n2);
- dot = MathUtility.Clamp1(dot);
- float phi = math.acos(dot);
-
- // 方向性
- float dir = math.dot(math.cross(n1, n2), e);
- if (sign != 0)
+ // 移動のみ
+ if (attributes[vindex].IsDontMove() == false)
{
- phi *= math.sign(dir);
- dir = 1; // lambdaを反転させるため
+ int cnt = cntPt[pindex];
+ if (cnt > 0)
+ {
+ int pindex2 = pindex * 3;
+ float3 add = new float3(sumPt[pindex2], sumPt[pindex2 + 1], sumPt[pindex2 + 2]);
+ add /= cnt;
+ // データは固定小数点なので戻す
+ add *= InterlockUtility.ToFloat;
+
+ nextPosArray[pindex] = nextPosArray[pindex] + add;
+ }
}
- float lambda =
- invMass0 * math.lengthsq(d0) +
- invMass1 * math.lengthsq(d1) +
- invMass2 * math.lengthsq(d2) +
- invMass3 * math.lengthsq(d3);
-
- if (lambda == 0.0f)
- return false;
-
- lambda = (phi - restAngle) / lambda * stiffness;
-
- if (dir > 0.0f)
- lambda = -lambda;
-
- float3 corr0 = -invMass0 * lambda * d0;
- float3 corr1 = -invMass1 * lambda * d1;
- float3 corr2 = -invMass2 * lambda * d2;
- float3 corr3 = -invMass3 * lambda * d3;
-
- addPosBuffer[0] = corr0;
- addPosBuffer[1] = corr1;
- addPosBuffer[2] = corr2;
- addPosBuffer[3] = corr3;
-
- return true;
+ // バッファクリア
+ tempCountBuffer[pindex] = 0;
+ tempVectorBufferA[pindex] = 0;
}
}
- [BurstCompile]
- struct SolveAggregateBufferJob : IJobParallelForDefer
+ static bool CalcVolume(
+ in float3x4 nextPosBuffer,
+ in float4 invMassBuffer,
+ float volumeRest,
+ float stiffness,
+ ref float3x4 addPosBuffer
+ )
{
- [Unity.Collections.ReadOnly]
- public NativeArray stepParticleIndexArray;
+ float3 nextPos0 = nextPosBuffer[0];
+ float3 nextPos1 = nextPosBuffer[1];
+ float3 nextPos2 = nextPosBuffer[2];
+ float3 nextPos3 = nextPosBuffer[3];
- // team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
+ float invMass0 = invMassBuffer[0];
+ float invMass1 = invMassBuffer[1];
+ float invMass2 = invMassBuffer[2];
+ float invMass3 = invMassBuffer[3];
- // vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
+ float volume = (1.0f / 6.0f) * math.dot(math.cross(nextPos1 - nextPos0, nextPos2 - nextPos0), nextPos3 - nextPos0);
+ volume *= VolumeScale; // 浮動小数点演算誤差回避
- // particle
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
+ float3 grad0 = math.cross(nextPos1 - nextPos2, nextPos3 - nextPos2);
+ float3 grad1 = math.cross(nextPos2 - nextPos0, nextPos3 - nextPos0);
+ float3 grad2 = math.cross(nextPos0 - nextPos1, nextPos3 - nextPos1);
+ float3 grad3 = math.cross(nextPos1 - nextPos0, nextPos2 - nextPos0);
- // constraint
- [Unity.Collections.ReadOnly]
- public NativeArray writeIndexArray;
- [Unity.Collections.ReadOnly]
- public NativeArray writeBuffer;
+ float lambda =
+ invMass0 * math.lengthsq(grad0) +
+ invMass1 * math.lengthsq(grad1) +
+ invMass2 * math.lengthsq(grad2) +
+ invMass3 * math.lengthsq(grad3);
+ lambda *= VolumeScale; // 浮動小数点演算誤差回避
- // ステップパーティクルごと
- public void Execute(int index)
+ if (math.abs(lambda) < 1e-06f)
+ return false;
+
+ lambda = stiffness * (volumeRest - volume) / lambda;
+
+ addPosBuffer[0] = lambda * invMass0 * grad0;
+ addPosBuffer[1] = lambda * invMass1 * grad1;
+ addPosBuffer[2] = lambda * invMass2 * grad2;
+ addPosBuffer[3] = lambda * invMass3 * grad3;
+
+ return true;
+ }
+
+ static bool CalcDihedralAngle(
+ float sign,
+ in float3x4 nextPosBuffer,
+ in float4 invMassBuffer,
+ float restAngle,
+ float stiffness,
+ ref float3x4 addPosBuffer
+ )
+ {
+ float3 nextPos0 = nextPosBuffer[0];
+ float3 nextPos1 = nextPosBuffer[1];
+ float3 nextPos2 = nextPosBuffer[2];
+ float3 nextPos3 = nextPosBuffer[3];
+
+ float invMass0 = invMassBuffer[0];
+ float invMass1 = invMassBuffer[1];
+ float invMass2 = invMassBuffer[2];
+ float invMass3 = invMassBuffer[3];
+
+ float3 e = nextPos3 - nextPos2;
+ float elen = math.length(e);
+ if (elen < 1e-08f)
+ return false;
+
+ float invElen = 1.0f / elen;
+
+ float3 n1 = math.cross(nextPos2 - nextPos0, nextPos3 - nextPos0);
+ float3 n2 = math.cross(nextPos3 - nextPos1, nextPos2 - nextPos1);
+
+ float n1_lengsq = math.lengthsq(n1);
+ float n2_lengsq = math.lengthsq(n2);
+
+ // 稀に発生する長さ0に対処
+ if (n1_lengsq == 0.0f || n2_lengsq == 0.0f)
+ return false;
+ //Develop.Assert(n1_lengsq > 0.0f);
+ //Develop.Assert(n2_lengsq > 0.0f);
+ n1 /= n1_lengsq;
+ n2 /= n2_lengsq;
+
+ float3 d0 = elen * n1;
+ float3 d1 = elen * n2;
+ float3 d2 = math.dot(nextPos0 - nextPos3, e) * invElen * n1 + math.dot(nextPos1 - nextPos3, e) * invElen * n2;
+ float3 d3 = math.dot(nextPos2 - nextPos0, e) * invElen * n1 + math.dot(nextPos2 - nextPos1, e) * invElen * n2;
+
+ n1 = math.normalize(n1);
+ n2 = math.normalize(n2);
+ float dot = math.dot(n1, n2);
+ dot = MathUtility.Clamp1(dot);
+ float phi = math.acos(dot);
+
+ float lambda =
+ invMass0 * math.lengthsq(d0) +
+ invMass1 * math.lengthsq(d1) +
+ invMass2 * math.lengthsq(d2) +
+ invMass3 * math.lengthsq(d3);
+
+ if (lambda == 0.0f)
+ return false;
+
+ // 方向性
+ float dirSign = math.sign(math.dot(math.cross(n1, n2), e));
+ if (sign != 0)
{
- // pindexのチームは有効であることが保証されている
- int pindex = stepParticleIndexArray[index];
- int teamId = teamIdArray[pindex];
- var tdata = teamDataArray[teamId];
- if (tdata.bendingPairChunk.IsValid == false)
- return;
-
- int l_index = pindex - tdata.particleChunk.startIndex;
-
- // 固定なら無効
- int vindex = tdata.proxyCommonChunk.startIndex + l_index;
- if (attributes[vindex].IsDontMove())
- return;
-
- // 書き込みバッファの値を平均化してnextPosに加算する
- uint pack = writeIndexArray[tdata.bendingWriteIndexChunk.startIndex + l_index];
- int cnt = DataUtility.Unpack12_20Hi(pack);
- int start = DataUtility.Unpack12_20Low(pack);
- int bufferIndex = tdata.bendingBufferChunk.startIndex + start;
- float3 add = 0;
- for (int i = 0; i < cnt; i++)
- {
- add += writeBuffer[bufferIndex + i];
- }
- if (cnt > 0)
- {
- add /= cnt;
- nextPosArray[pindex] = nextPosArray[pindex] + add;
- }
+ // 方向性あり(DirectionDihedralAngle)
+ phi *= dirSign;
}
+ else
+ {
+ // 方向性なし(DihedralAngle)
+ lambda *= dirSign;
+ }
+
+ lambda = (restAngle - phi) / lambda * stiffness;
+
+ float3 corr0 = -invMass0 * lambda * d0;
+ float3 corr1 = -invMass1 * lambda * d1;
+ float3 corr2 = -invMass2 * lambda * d2;
+ float3 corr3 = -invMass3 * lambda * d3;
+
+ addPosBuffer[0] = corr0;
+ addPosBuffer[1] = corr1;
+ addPosBuffer[2] = corr2;
+ addPosBuffer[3] = corr3;
+
+ return true;
}
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs.meta
index ec0bb69e..192ef7ea 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Constraints/TriangleBendingConstraint.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs
index b8423828..831413c1 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs
@@ -1,4 +1,7 @@
-using System.Collections.Generic;
+// Magica Cloth 2.
+// Copyright (c) 2025 MagicaSoft.
+// https://magicasoft.jp
+using System.Collections.Generic;
using UnityEngine;
namespace MagicaCloth2
@@ -83,8 +86,57 @@ namespace MagicaCloth2
///
public List cameraCullingRenderers = new List();
+ ///
+ /// 距離カリングの状態と距離
+ /// Distance Culling State and Distance.
+ /// [OK] Runtime changes.
+ /// [NG] Export/Import with Presets
+ ///
+ public CheckSliderSerializeData distanceCullingLength;
+
+ ///
+ /// 距離カリングのフェード割合(0.0 ~ 1.0)
+ /// Distance culling fade rate (0.0 to 1.0).
+ /// [OK] Runtime changes.
+ /// [NG] Export/Import with Presets
+ ///
+ [Range(0.0f, 1.0f)]
+ public float distanceCullingFadeRatio;
+
+ ///
+ /// 距離カリングの測定対象(None=メインカメラ)
+ /// Distance culling measurement target (None = main camera).
+ /// [OK] Runtime changes.
+ /// [NG] Export/Import with Presets
+ ///
+ public GameObject distanceCullingReferenceObject;
+
+ //=========================================================================================
+ public struct CullingParams
+ {
+ public bool useDistanceCulling;
+ public float distanceCullingLength;
+ public float distanceCullingFadeRatio;
+
+ public void Convert(CullingSettings cullingSettings)
+ {
+ useDistanceCulling = cullingSettings.distanceCullingLength.use;
+ distanceCullingLength = cullingSettings.distanceCullingLength.value;
+ distanceCullingFadeRatio = cullingSettings.distanceCullingFadeRatio;
+ }
+ }
+
+ //=========================================================================================
+ public CullingSettings()
+ {
+ distanceCullingLength = new CheckSliderSerializeData(false, 30.0f);
+ distanceCullingFadeRatio = 0.2f;
+ }
+
public void DataValidate()
{
+ distanceCullingLength.DataValidate(0.0f, Define.System.DistanceCullingMaxLength);
+ distanceCullingFadeRatio = Mathf.Clamp01(distanceCullingFadeRatio);
}
public CullingSettings Clone()
@@ -94,6 +146,9 @@ namespace MagicaCloth2
cameraCullingMode = cameraCullingMode,
cameraCullingMethod = cameraCullingMethod,
cameraCullingRenderers = new List(cameraCullingRenderers),
+ distanceCullingLength = distanceCullingLength.Clone(),
+ distanceCullingFadeRatio = distanceCullingFadeRatio,
+ distanceCullingReferenceObject = distanceCullingReferenceObject,
};
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs.meta
index c1315ab2..02459dd6 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/CullingSettings.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs.meta
index f1498d3c..4c29e957 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/CurveSerializeData.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs
index 59a73f0a..347d00d3 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs
@@ -19,10 +19,8 @@ namespace MagicaCloth2
public bool enable = false;
///
- /// bones for skinning.
- /// Calculated from the parent-child structure line of bones registered here.
- /// スキニング用ボーン
- /// ここに登録されたボーンの親子構造ラインから算出される
+ /// Bones for custom skinning.
+ /// カスタムスキニング用ボーン
/// [NG] Runtime changes.
/// [NG] Export/Import with Presets
///
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs.meta
index aaea93b8..76a99c94 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/CustomSkinningSettings.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs.meta
index bb0f0b0a..a2e95439 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/GizmoSerializeData.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs
index 7b6d414b..0d3d0f02 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs
@@ -42,7 +42,14 @@ namespace MagicaCloth2
/// General processing.
///
private ClothProcess process = new ClothProcess();
- public ClothProcess Process { get { process.cloth = this; return process; } }
+ public ClothProcess Process
+ {
+ get
+ {
+ process.cloth = this;
+ return process;
+ }
+ }
///
/// Cloth component transform.
@@ -53,7 +60,14 @@ namespace MagicaCloth2
///
/// Synchronization target.
///
- public MagicaCloth SyncCloth => SerializeData.IsBoneSpring() ? null : SerializeData.selfCollisionConstraint.GetSyncPartner();
+ public MagicaCloth SyncPartnerCloth
+ {
+ get
+ {
+ var syncCloth = SerializeData.IsBoneSpring() ? null : SerializeData.selfCollisionConstraint.GetSyncPartner();
+ return syncCloth == this ? null : syncCloth;
+ }
+ }
///
/// Check if the cloth component is in a valid state.
@@ -66,6 +80,14 @@ namespace MagicaCloth2
}
//=========================================================================================
+ private void Reset()
+ {
+#if UNITY_EDITOR
+ // Automatically generate pre-build ID
+ serializeData2.preBuildData.buildId = PreBuildSerializeData.GenerateBuildID();
+#endif
+ }
+
private void OnValidate()
{
Process.DataUpdate();
@@ -73,10 +95,11 @@ namespace MagicaCloth2
private void Awake()
{
- Process.Init();
-
- // If Awake() is called, OnDestroy() will also be called, so remove it from monitoring.
- MagicaManager.Team.RemoveMonitoringProcess(Process);
+ if (MagicaManager.initializationLocation == MagicaManager.InitializationLocation.Awake)
+ {
+ Process.Init();
+ MagicaManager.Team.RemoveMonitoringProcess(Process);
+ }
}
private void OnEnable()
@@ -91,6 +114,12 @@ namespace MagicaCloth2
void Start()
{
+ if (MagicaManager.initializationLocation == MagicaManager.InitializationLocation.Start)
+ {
+ Process.Init();
+ MagicaManager.Team.RemoveMonitoringProcess(Process);
+ }
+
Process.AutoBuild();
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs.meta
index 792d34c9..c0c1e0d3 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs.meta
@@ -4,8 +4,15 @@ MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
- executionOrder: 0
+ executionOrder: 5
icon: {fileID: 2800000, guid: cf7e3400035e987478c3a19e57b4cf75, type: 3}
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaCloth.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs
index 8cd0acbe..a633ba32 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs
@@ -29,8 +29,14 @@ namespace MagicaCloth2
/// Event after completion of cloth data construction.
/// (true = Success, false = Failure)
///
- public Action OnBuildComplete;
+ public Action OnBuildComplete;
+ ///
+ /// レンダラーメッシュ変更後イベント
+ /// Renderer mesh change event.
+ /// (true = Change to custom mesh, false = Change to original mesh)
+ ///
+ public Action OnRendererMeshChange;
///
/// 初期化を実行します
@@ -67,41 +73,74 @@ namespace MagicaCloth2
/// true=start build. false=build failed.
public bool BuildAndRun()
{
- if (Application.isPlaying == false)
- return false;
+ bool ret = false;
+ bool buildComplate = true;
- DisableAutoBuild();
-
- if (Process.IsState(ClothProcess.State_Build))
+ try
{
- Develop.LogError($"Already built.:{this.name}");
- return false;
- }
+ if (Application.isPlaying == false)
+ throw new MagicaClothProcessingException();
- // initialize generated data.
- if (Process.GenerateInitialization() == false)
- return false;
+ DisableAutoBuild();
- // setting by type.
- switch (serializeData.clothType)
- {
- case ClothProcess.ClothType.BoneCloth:
- case ClothProcess.ClothType.BoneSpring:
- // BoneCloth用のセレクションデータの作成
- // ただしセレクションデータが存在し、かつユーザー定義されている場合は作成しない
- var nowSelection = serializeData2.selectionData;
- if (nowSelection == null || nowSelection.IsValid() == false || nowSelection.IsUserEdit() == false)
+ if (Process.IsState(ClothProcess.State_Build))
+ {
+ Develop.LogError($"Already built.:{this.name}");
+ throw new MagicaClothProcessingException();
+ }
+
+ // initialize generated data.
+ if (Process.GenerateInitialization() == false)
+ throw new MagicaClothProcessingException();
+
+ // check Pre-Build
+ bool usePreBuildData = serializeData2.preBuildData.UsePreBuild();
+
+ if (usePreBuildData == false)
+ {
+ // Runtime Build.
+ // setting by type.
+ switch (serializeData.clothType)
{
- if (Process.GenerateBoneClothSelection() == false)
- return false;
+ case ClothProcess.ClothType.BoneCloth:
+ case ClothProcess.ClothType.BoneSpring:
+ // BoneCloth用のセレクションデータの作成
+ // ただしセレクションデータが存在し、かつユーザー定義されている場合は作成しない
+ var nowSelection = serializeData2.selectionData;
+ if (nowSelection == null || nowSelection.IsValid() == false || nowSelection.IsUserEdit() == false)
+ {
+ if (Process.GenerateBoneClothSelection() == false)
+ throw new MagicaClothProcessingException();
+ }
+ break;
}
- break;
+
+ // build and run.
+ ret = Process.StartRuntimeBuild();
+ if (ret)
+ buildComplate = false; // OnBuildCompleteはランタイム構築後に呼ばれる
+ }
+ else
+ {
+ // pre-build
+ ret = Process.PreBuildDataConstruction();
+ }
+ }
+ catch (MagicaClothProcessingException)
+ {
+ }
+ catch (Exception exception)
+ {
+ Debug.LogException(exception);
+ }
+ finally
+ {
+ // ビルド完了イベント
+ if (buildComplate)
+ OnBuildComplete?.Invoke(this, ret);
}
- // build and run.
- Process.StartBuild();
-
- return true;
+ return ret;
}
///
@@ -123,7 +162,7 @@ namespace MagicaCloth2
var replaceDict = new Dictionary();
foreach (var t in useTransformSet)
{
- if (targetTransformDict.ContainsKey(t.name))
+ if (t && targetTransformDict.ContainsKey(t.name))
{
replaceDict.Add(t.GetInstanceID(), targetTransformDict[t.name]);
}
@@ -133,6 +172,18 @@ namespace MagicaCloth2
Process.ReplaceTransform(replaceDict);
}
+ ///
+ /// コンポーネントが保持するすべてのトランスフォームを取得します。
+ /// Gets all the transforms held by the component.
+ ///
+ ///
+ public HashSet GetUsedTransform()
+ {
+ var useTransformSet = new HashSet();
+ Process.GetUsedTransform(useTransformSet);
+ return useTransformSet;
+ }
+
///
/// パラメータの変更を通知
@@ -197,8 +248,8 @@ namespace MagicaCloth2
// Reset
tdata.flag.SetBits(TeamManager.Flag_Reset, true);
tdata.flag.SetBits(TeamManager.Flag_TimeReset, true);
- tdata.flag.SetBits(TeamManager.Flag_CullingKeep, false);
- Process.SetState(ClothProcess.State_CullingKeep, false);
+ tdata.flag.SetBits(TeamManager.Flag_CameraCullingKeep, false);
+ Process.SetState(ClothProcess.State_CameraCullingKeep, false);
Process.UpdateRendererUse();
}
}
@@ -251,5 +302,50 @@ namespace MagicaCloth2
Process.SetSkipWriting(sw);
}
}
+
+ private RenderData GetRenderData(Renderer ren)
+ {
+ if (IsValid() == false || ren == null)
+ return null;
+ int handle = ren.GetInstanceID();
+ return MagicaManager.Render.GetRendererData(handle);
+ }
+
+ ///
+ /// MeshClothのオリジナルメッシュを取得します
+ /// Get the original mesh of MeshCloth.
+ ///
+ ///
+ /// null if not found
+ public Mesh GetOriginalMesh(Renderer ren)
+ {
+ return GetRenderData(ren)?.originalMesh ?? null;
+ }
+
+ ///
+ /// MeshClothのカスタムメッシュを取得します
+ /// Get the custom mesh for MeshCloth.
+ ///
+ ///
+ /// null if not found
+ public Mesh GetCustomMesh(Renderer ren)
+ {
+ return GetRenderData(ren)?.customMesh ?? null;
+ }
+
+ ///
+ /// MeshClothのSkinnedMeshRendererに設定されているカスタムボーンリストを取得します
+ /// カスタムボーンリストはオリジナルのBonesからスキニングに不要なTransformをnullに設定し、
+ /// また最後にレンダラーのTransformが追加されるなど加工されているので注意してください。
+ /// Gets the custom bone list set for the SkinnedMeshRenderer of MeshCloth.
+ /// Please note that the custom bone list has been processed by setting Transforms
+ /// that are not necessary for skinning to null from the original Bones, and adding the renderer Transform at the end.
+ ///
+ ///
+ /// null if not found
+ public List GetCustomBones(Renderer ren)
+ {
+ return GetRenderData(ren)?.transformList ?? null;
+ }
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs.meta
index a97c3184..14cb7890 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAPI.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs
new file mode 100644
index 00000000..88e3882d
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs
@@ -0,0 +1,130 @@
+// Magica Cloth 2.
+// Copyright (c) 2024 MagicaSoft.
+// https://magicasoft.jp
+
+using UnityEngine;
+
+namespace MagicaCloth2
+{
+ ///
+ /// プロパティをアニメーションから制御するためのラッパー.
+ /// Wrapper for controlling properties from animation.
+ ///
+ public partial class MagicaCloth
+ {
+ [HideInInspector]
+ public float animationPoseRatioProperty;
+ float _animationPoseRatioProperty;
+
+ [HideInInspector]
+ public float gravityProperty;
+ float _gravityProperty;
+
+ [HideInInspector]
+ public float dampingProperty;
+ float _dampingProperty;
+
+ [HideInInspector]
+ public float worldInertiaProperty;
+ float _worldInertiaProperty;
+
+ [HideInInspector]
+ public float localInertiaProperty;
+ float _localInertiaProperty;
+
+ [HideInInspector]
+ public float windInfluenceProperty;
+ float _windInfluenceProperty;
+
+ [HideInInspector]
+ public float blendWeightProperty;
+ float _blendWeightProperty;
+
+ //=========================================================================================
+ internal void InitAnimationProperty()
+ {
+ animationPoseRatioProperty = serializeData.animationPoseRatio;
+ _animationPoseRatioProperty = animationPoseRatioProperty;
+
+ gravityProperty = serializeData.gravity;
+ _gravityProperty = gravityProperty;
+
+ dampingProperty = serializeData.damping.value;
+ _dampingProperty = dampingProperty;
+
+ worldInertiaProperty = serializeData.inertiaConstraint.worldInertia;
+ _worldInertiaProperty = worldInertiaProperty;
+
+ localInertiaProperty = serializeData.inertiaConstraint.localInertia;
+ _localInertiaProperty = localInertiaProperty;
+
+ windInfluenceProperty = serializeData.wind.influence;
+ _windInfluenceProperty = windInfluenceProperty;
+
+ blendWeightProperty = serializeData.blendWeight;
+ _blendWeightProperty = blendWeightProperty;
+ }
+
+ ///
+ /// アニメーションによりMagicaClothのプロパティが変更されたときに呼び出される.
+ /// Called when a property of MagicaCloth changes due to animation.
+ ///
+ void OnDidApplyAnimationProperties()
+ {
+ if (Application.isPlaying)
+ {
+ //Debug.Log($"Animated property changes. F:{Time.frameCount}");
+
+ if (animationPoseRatioProperty != _animationPoseRatioProperty)
+ {
+ _animationPoseRatioProperty = animationPoseRatioProperty;
+ serializeData.animationPoseRatio = animationPoseRatioProperty;
+ SetParameterChange();
+ }
+
+ if (gravityProperty != _gravityProperty)
+ {
+ _gravityProperty = gravityProperty;
+ serializeData.gravity = gravityProperty;
+ SetParameterChange();
+ }
+
+ if (dampingProperty != _dampingProperty)
+ {
+ _dampingProperty = dampingProperty;
+ serializeData.damping.value = dampingProperty;
+ SetParameterChange();
+ }
+
+ if (worldInertiaProperty != _worldInertiaProperty)
+ {
+ _worldInertiaProperty = worldInertiaProperty;
+ serializeData.inertiaConstraint.worldInertia = worldInertiaProperty;
+ SetParameterChange();
+ }
+
+ if (localInertiaProperty != _localInertiaProperty)
+ {
+ _localInertiaProperty = localInertiaProperty;
+ serializeData.inertiaConstraint.localInertia = localInertiaProperty;
+ SetParameterChange();
+ }
+
+ if (windInfluenceProperty != _windInfluenceProperty)
+ {
+ _windInfluenceProperty = windInfluenceProperty;
+ serializeData.wind.influence = windInfluenceProperty;
+ SetParameterChange();
+ }
+
+ if (blendWeightProperty != _blendWeightProperty)
+ {
+ _blendWeightProperty = blendWeightProperty;
+ serializeData.blendWeight = blendWeightProperty;
+ SetParameterChange();
+ }
+ }
+ }
+ }
+}
+
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs.meta
new file mode 100644
index 00000000..2990ea55
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs.meta
@@ -0,0 +1,18 @@
+fileFormatVersion: 2
+guid: fea7c53425d793a44b3d484072c68bde
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/MagicaClothAnimationProperty.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs.meta
index 5bf54d51..1e3b2589 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/NormalAlignmentSettings.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs
index 11284afa..1f4e1b65 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs
@@ -212,13 +212,7 @@ namespace MagicaCloth2
public void Fill(VertexAttribute attr)
{
-#if UNITY_2020
- int cnt = Count;
- for (int i = 0; i < cnt; i++)
- attributes[i] = attr;
-#else
Array.Fill(attributes, attr);
-#endif
}
//=========================================================================================
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs.meta
index c14fff5f..85b63b3e 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/SelectionData.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs
index c39eb9cd..fd046db0 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs
@@ -127,12 +127,12 @@ namespace MagicaCloth2
public void OnDisable()
{
- MagicaManager.Wind.SetEnable(WindId, false);
+ MagicaManager.Wind?.SetEnable(WindId, false);
}
public void OnDestroy()
{
- MagicaManager.Wind.RemoveWind(WindId);
+ MagicaManager.Wind?.RemoveWind(WindId);
WindId = -1;
}
@@ -200,8 +200,9 @@ namespace MagicaCloth2
public void SetWindDirection(Vector3 dir, bool localSpace = false)
{
Vector3 lv = localSpace ? dir : transform.InverseTransformDirection(dir);
- directionAngleX = Mathf.Atan2(lv.z, lv.x) * Mathf.Rad2Deg;
- directionAngleY = Mathf.Atan2(lv.z, lv.y) * Mathf.Rad2Deg;
+ var angles = Quaternion.FromToRotation(Vector3.forward, lv).eulerAngles;
+ directionAngleX = angles.x > 180 ? angles.x - 360 : angles.x;
+ directionAngleY = angles.y > 180 ? angles.y - 360 : angles.y;
}
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs.meta
index dd632e1e..af8a80d6 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/MagicaWindZone.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs.meta
index f65d419e..2e5bea7c 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/WindParams.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs.meta
index 35cbcae2..3223aa51 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Cloth/Wind/WindSettings.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs b/Assets/External/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs
index fd8f1771..b81b1a95 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs
@@ -34,6 +34,8 @@ namespace MagicaCloth2
RenderMesh_UnknownWarning = 10100,
RenderMesh_VertexWeightIs5BonesOrMore,
+ Init_NonUniformScale = 10200,
+
///////////////////////////////////////////////////////////////////
// Error(20000 - )
///////////////////////////////////////////////////////////////////
@@ -42,11 +44,15 @@ namespace MagicaCloth2
// Validating serialized data
SerializeData_InvalidData = 20050,
SerializeData_Over31Renderers,
+ SerializeData_DuplicateRootBone,
+ SerializeData_DuplicateRenderer,
// init
Init_InvalidData = 20100,
Init_InvalidPaintMap,
Init_PaintMapNotReadable,
+ Init_ScaleIsZero,
+ Init_NegativeScale,
// RenderSetup
RenderSetup_Exception = 20200,
@@ -76,6 +82,11 @@ namespace MagicaCloth2
CreateCloth_InvalidPaintMap,
CreateCloth_PaintMapNotReadable,
CreateCloth_PaintMapCountMismatch,
+ CreateCloth_CanNotStart,
+ CreateCloth_VertexAttributeListCountMismatch,
+ CreateCloth_VertexAttributeListIsNull,
+ CreateCloth_VertexAttributeListDataMismatch,
+ CreateCloth_InvalidVertexAttributeData,
// Reduction
Reduction_Exception = 20500,
@@ -131,6 +142,41 @@ namespace MagicaCloth2
MagicaMesh_Invalid,
MagicaMesh_InvalidRenderer,
MagicaMesh_InvalidMeshFilter,
+
+ // PreBuildData
+ PreBuildData_UnknownError = 22600,
+ PreBuildData_MagicaClothException,
+ PreBuildData_VirtualMeshDeserializationException,
+ PreBuildData_VerificationResult,
+ PreBuildData_VersionMismatch,
+ PreBuildData_InvalidClothData,
+ PreBuildData_Empty,
+ PreBuildData_InvalidScale,
+
+ // PreBuild
+ PreBuild_UnknownError = 22700,
+ PreBuild_Exception,
+ PreBuild_InvalidPreBuildData,
+ PreBuild_InvalidRenderSetupData,
+ PreBuild_SetupDeserializationError,
+
+ // PreBuild Deserialization
+ Deserialization_UnknownError = 22800,
+ Deserialization_Exception,
+
+ // Init SerializeData
+ InitSerializeData_UnknownError = 22900,
+ InitSerializeData_InvalidHash,
+ InitSerializeData_InvalidVersion,
+ InitSerializeData_InvalidSetupData,
+ InitSerializeData_ClothTypeMismatch,
+ InitSerializeData_SetupCountMismatch,
+ InitSerializeData_CustomSkinningBoneCountMismatch,
+ InitSerializeData_MeshClothSetupValidationError,
+ InitSerializeData_BoneClothSetupValidationError,
+ InitSerializeData_BoneSpringSetupValidationError,
+ InitSerializeData_DeserializationError,
+ InitSerializeData_InvalidCloneMesh,
}
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs.meta
index 59eeb12b..0ecbba0b 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Define/ResultDefine.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs b/Assets/External/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs
index 7af5cb07..36f45a2d 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs
@@ -17,6 +17,11 @@ namespace MagicaCloth2
///
public const string DefineSymbol = "MAGICACLOTH2";
+ ///
+ /// 現在有効なPreBuildの最新バージョン
+ ///
+ public const int LatestPreBuildVersion = 2;
+
///
/// 計算を省略する最小の浮動小数点数
///
@@ -72,6 +77,16 @@ namespace MagicaCloth2
///
public const float SameSurfaceAngle = 80.0f;
+ ///
+ /// 未来予測時のルートからの距離制限倍率
+ ///
+ public const float MaxDistanceRatioFutuerPrediction = 1.3f;
+
+ ///
+ /// 分割ジョブを適用するプロキシメッシュメッシュの頂点数
+ ///
+ public const int SplitProxyMeshVertexCount = 300;
+
///
/// [Reduction]
/// 有効フラグ。常にtrueとする。
@@ -319,7 +334,19 @@ namespace MagicaCloth2
/// [Self Collision]
/// 反復回数
///
- public const int SelfCollisionSolverIteration = 4;
+ public const int SelfCollisionSolverIteration = 4; // 4
+
+ ///
+ /// [Self Collision]
+ /// 無効グリッド座標
+ ///
+ public const int SelfCollisionIgnoreGrid = 1000000;
+
+ ///
+ /// [Self Collision]
+ /// 交差判定の分割数
+ ///
+ public const int SelfCollisionIntersectDiv = 2; // 8
///
/// [Self Collision]
@@ -351,12 +378,6 @@ namespace MagicaCloth2
///
public static readonly float SelfCollisionPointTriangleAngleCos = math.cos(math.radians(60.0f));
- ///
- /// [Self Collision]
- /// 交差判定の分割数
- ///
- public const int SelfCollisionIntersectDiv = 8;
-
///
/// [Self Collision]
/// Thicknessの最小値(m)
@@ -398,6 +419,12 @@ namespace MagicaCloth2
/// BoneSpring利用時のfriction値
///
public const float BoneSpringCollisionFriction = 0.5f;
+
+ ///
+ /// [Culling]
+ /// 距離カリングの最大距離
+ ///
+ public const float DistanceCullingMaxLength = 100.0f;
}
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs.meta
index a4b675b2..c066e7dd 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Define/SystemDefine.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Interface/ICount.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Interface/ICount.cs.meta
index c402a984..a83f39e2 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Interface/ICount.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Interface/ICount.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Interface/ICount.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs.meta
index 1f38f5f0..5de1145f 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Interface/IDataValidate.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Interface/ITransform.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Interface/ITransform.cs.meta
index b801f1d6..3933622e 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Interface/ITransform.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Interface/ITransform.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Interface/ITransform.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Interface/IValid.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Interface/IValid.cs.meta
index cf8369c6..a6fc7785 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Interface/IValid.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Interface/IValid.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Interface/IValid.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs
index 9e3d6098..26856b2f 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs
@@ -15,7 +15,7 @@ namespace MagicaCloth2
public class ClothManager : IManager, IValid
{
// すべて
- internal HashSet clothSet = new HashSet();
+ internal HashSet clothSet = new HashSet(256);
// BoneCloth,BoneSpring
internal HashSet boneClothSet = new HashSet();
@@ -50,6 +50,7 @@ namespace MagicaCloth2
// 更新処理
MagicaManager.afterEarlyUpdateDelegate -= OnEarlyClothUpdate;
+ MagicaManager.firstPreUpdateDelegate -= OnFirstPreUpdate;
MagicaManager.afterLateUpdateDelegate -= OnAfterLateUpdate;
MagicaManager.beforeLateUpdateDelegate -= OnBeforeLateUpdate;
}
@@ -69,6 +70,7 @@ namespace MagicaCloth2
// 更新処理
MagicaManager.afterEarlyUpdateDelegate += OnEarlyClothUpdate;
+ MagicaManager.firstPreUpdateDelegate += OnFirstPreUpdate;
MagicaManager.afterLateUpdateDelegate += OnAfterLateUpdate;
MagicaManager.beforeLateUpdateDelegate += OnBeforeLateUpdate;
@@ -118,6 +120,9 @@ namespace MagicaCloth2
break;
}
+ // チームマネージャの作業バッファへ登録
+ MagicaManager.Team.comp2TeamIdMap.Add(cprocess.cloth.GetInstanceID(), teamId);
+
return teamId;
}
@@ -140,11 +145,15 @@ namespace MagicaCloth2
///
void OnEarlyClothUpdate()
{
- if (MagicaManager.Team.ActiveTeamCount > 0)
+ //Debug.Log($"OnEarlyClothUpdate. F:{Time.frameCount}");
+ if (MagicaManager.Team.TrueTeamCount > 0) // カリング判定があるのでDisableチームもまわす必要がある
{
- //Debug.Log($"TransformRestoreUpdate. F:{Time.frameCount}");
- // チームカリング更新
- MagicaManager.Team.TeamCullingUpdate();
+ // カメラカリング更新
+ if (MagicaManager.Team.ActiveTeamCount > 0)
+ {
+ // この更新は次のTransform復元の前に行う必要がある
+ MagicaManager.Team.CameraCullingPostProcess();
+ }
// BoneClothのTransform復元更新
ClearMasterJob();
@@ -153,6 +162,25 @@ namespace MagicaCloth2
}
}
+ ///
+ /// PreUpdate開始時に実行される更新処理
+ ///
+ void OnFirstPreUpdate()
+ {
+ //Debug.Log($"OnFirstPreUpdate. F:{Time.frameCount}");
+ if (MagicaManager.Team.TrueTeamCount > 0) // カリング判定があるのでDisableチームもまわす必要がある
+ {
+ //Debug.Log($"existFixedTeam:{MagicaManager.Bone.existFixedTeam.Value}");
+ // FixedUpdateが0回かつFixedTeamが存在する場合のみ
+ if (MagicaManager.Time.FixedUpdateCount == 0 && MagicaManager.Bone.existFixedTeam.Value)
+ {
+ ClearMasterJob();
+ masterJob = MagicaManager.Bone.RestoreBaseTransform(masterJob);
+ CompleteMasterJob();
+ }
+ }
+ }
+
void OnBeforeLateUpdate()
{
if (MagicaManager.Time.updateLocation == TimeManager.UpdateLocation.BeforeLateUpdate)
@@ -166,7 +194,9 @@ namespace MagicaCloth2
}
//=========================================================================================
- static readonly ProfilerMarker startClothUpdateMainProfiler = new ProfilerMarker("StartClothUpdate.Main");
+ static readonly ProfilerMarker startClothUpdateTimeProfiler = new ProfilerMarker("StartClothUpdate.Time");
+ static readonly ProfilerMarker startClothUpdateTeamProfiler = new ProfilerMarker("StartClothUpdate.Team");
+ static readonly ProfilerMarker startClothUpdatePrePareProfiler = new ProfilerMarker("StartClothUpdate.Prepare");
static readonly ProfilerMarker startClothUpdateScheduleProfiler = new ProfilerMarker("StartClothUpdate.Schedule");
///
@@ -177,13 +207,16 @@ namespace MagicaCloth2
if (MagicaManager.IsPlaying() == false)
return;
+ // ■コンポーネント0なら終了
+ var tm = MagicaManager.Team;
+ if (tm.TrueTeamCount == 0)
+ return;
+
//-----------------------------------------------------------------
// シミュレーション開始イベント
MagicaManager.OnPreSimulation?.Invoke();
//-----------------------------------------------------------------
- var tm = MagicaManager.Team;
- var vm = MagicaManager.VMesh;
var sm = MagicaManager.Simulation;
var bm = MagicaManager.Bone;
var wm = MagicaManager.Wind;
@@ -192,22 +225,21 @@ namespace MagicaCloth2
//Develop.DebugLog($"StartClothUpdate. F:{Time.frameCount}, dtime:{Time.deltaTime}, stime:{Time.smoothDeltaTime}");
//-----------------------------------------------------------------
- startClothUpdateMainProfiler.Begin();
// ■時間マネージャ更新
+ startClothUpdateTimeProfiler.Begin();
MagicaManager.Time.FrameUpdate();
+ startClothUpdateTimeProfiler.End();
// ■常に実行するチーム更新
+ startClothUpdateTeamProfiler.Begin();
tm.AlwaysTeamUpdate();
+ startClothUpdateTeamProfiler.End();
// ■ここで実行チーム数が0ならば終了
if (tm.ActiveTeamCount == 0)
- {
- startClothUpdateMainProfiler.End();
return;
- }
- int maxUpdateCount = tm.maxUpdateCount.Value;
- //Debug.Log($"maxUpdateCount:{maxUpdateCount}");
+ startClothUpdatePrePareProfiler.Begin();
// ■常に実行する風ゾーン更新
wm.AlwaysWindUpdate();
@@ -215,106 +247,32 @@ namespace MagicaCloth2
// ■作業バッファ更新
sm.WorkBufferUpdate();
- startClothUpdateMainProfiler.End();
+ startClothUpdatePrePareProfiler.End();
//-----------------------------------------------------------------
-#if true
startClothUpdateScheduleProfiler.Begin();
+
// マスタージョブ初期化
ClearMasterJob();
// ■トランスフォーム情報の読み込み
- masterJob = bm.ReadTransform(masterJob);
+ masterJob = bm.ReadTransformSchedule(masterJob);
- // ■プロキシメッシュをスキニングし基本姿勢を求める
- masterJob = vm.PreProxyMeshUpdate(masterJob);
-
- //-----------------------------------------------------------------
- // チームのセンター姿勢の決定と慣性用の移動量計算
- masterJob = tm.CalcCenterAndInertiaAndWind(masterJob);
-
- // パーティクルリセットの適用
- masterJob = sm.PreSimulationUpdate(masterJob);
-
- // ■コライダーのローカル姿勢を求める
- masterJob = MagicaManager.Collider.PreSimulationUpdate(masterJob);
-
- //-----------------------------------------------------------------
- // ■クロスシミュレーション実行
- // ステップ実行
- for (int i = 0; i < maxUpdateCount; i++)
- {
- masterJob = sm.SimulationStepUpdate(maxUpdateCount, i, masterJob);
- }
-
- //-----------------------------------------------------------------
- // 表示位置の決定
- masterJob = sm.CalcDisplayPosition(masterJob);
-
- //-----------------------------------------------------------------
- // ■クロスシミュレーション後の頂点姿勢計算
- // プロキシメッシュの頂点から法線接線を求め姿勢を確定させる
- // ラインがある場合はベースラインごとに姿勢を整える
- // BoneClothの場合は頂点姿勢を連動するトランスフォームデータにコピーする
- masterJob = vm.PostProxyMeshUpdate(masterJob);
-
- // マッピングメッシュ
- int mappingCount = tm.MappingCount;
- if (mappingCount > 0)
- {
- // マッピングメッシュ頂点姿勢をプロキシメッシュからスキニングし求める
- // マッピングメッシュのローカル空間に座標変換する
- masterJob = vm.PostMappingMeshUpdate(masterJob);
-
- // レンダーデータへ反映する
- foreach (var cprocess in meshClothSet)
- {
- if (cprocess == null || cprocess.IsValid() == false || cprocess.IsEnable == false)
- continue;
-
- // カリングによる非表示中ならば書き込まない
- if (cprocess.IsCullingInvisible())
- continue;
-
- int cnt = cprocess.renderMeshInfoList.Count;
- for (int i = 0; i < cnt; i++)
- {
- var info = cprocess.renderMeshInfoList[i];
- var renderData = MagicaManager.Render.GetRendererData(info.renderHandle);
-
- // Position/Normal書き込み
- masterJob = renderData.UpdatePositionNormal(info.mappingChunk, masterJob);
-
- // BoneWeight書き込み
- if (renderData.ChangeCustomMesh)
- {
- masterJob = renderData.UpdateBoneWeight(info.mappingChunk, masterJob);
- }
- }
- }
- }
-
- //-----------------------------------------------------------------
- // ■BoneClothのTransformへの書き込み
- masterJob = bm.WriteTransform(masterJob);
-
- //-----------------------------------------------------------------
- // ■コライダー更新後処理
- masterJob = MagicaManager.Collider.PostSimulationUpdate(masterJob);
-
- // ■チーム更新後処理
- masterJob = tm.PostTeamUpdate(masterJob);
+ // ■シミュレーションジョブ
+ masterJob = sm.ClothSimulationSchedule(masterJob);
startClothUpdateScheduleProfiler.End();
+ //-----------------------------------------------------------------
+ //JobHandle.ScheduleBatchedJobs();
//-----------------------------------------------------------------
- // ジョブを即実行
- //JobHandle.ScheduleBatchedJobs();
+ // ■ジョブ完了待ちの間に行う処理
+ // カメラカリングの準備
+ tm.CameraCullingPreProcess();
//-----------------------------------------------------------------
// ■現在は即時実行のためここでジョブの完了待ちを行う
CompleteMasterJob();
-#endif
//-----------------------------------------------------------------
// シミュレーション終了イベント
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs.meta
index e53b7b07..61ce8db9 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/ClothManager.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs
new file mode 100644
index 00000000..a4436f7c
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs
@@ -0,0 +1,301 @@
+// Magica Cloth 2.
+// Copyright (c) 2024 MagicaSoft.
+// https://magicasoft.jp
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Unity.Profiling;
+using UnityEngine;
+
+namespace MagicaCloth2
+{
+ ///
+ /// PreBuildの管理マネージャ
+ ///
+ public class PreBuildManager : IManager, IValid
+ {
+ ///
+ /// 共有ビルドデータの復元データ
+ ///
+ internal class ShareDeserializationData : IDisposable
+ {
+ internal string buildId;
+ internal ResultCode result;
+ internal int referenceCount;
+
+ internal List renderSetupDataList = new List();
+ internal VirtualMesh proxyMesh = null;
+ internal List renderMeshList = new List();
+
+ internal DistanceConstraint.ConstraintData distanceConstraintData;
+ internal TriangleBendingConstraint.ConstraintData bendingConstraintData;
+ internal InertiaConstraint.ConstraintData inertiaConstraintData;
+
+ public void Dispose()
+ {
+ foreach (var data in renderSetupDataList)
+ {
+ if (data != null)
+ {
+ data.isManaged = false;
+ data.Dispose();
+ }
+ }
+ renderSetupDataList.Clear();
+
+ if (proxyMesh != null)
+ {
+ proxyMesh.isManaged = false;
+ proxyMesh.Dispose();
+ proxyMesh = null;
+ }
+
+ foreach (var rmesh in renderMeshList)
+ {
+ if (rmesh != null)
+ {
+ rmesh.isManaged = false;
+ rmesh.Dispose();
+ }
+ }
+ renderMeshList.Clear();
+
+ distanceConstraintData = null;
+ bendingConstraintData = null;
+ inertiaConstraintData = null;
+
+ buildId = string.Empty;
+ result.Clear();
+ referenceCount = 0;
+ }
+
+ public void Deserialize(SharePreBuildData sharePreBuilddata)
+ {
+ result.SetProcess();
+
+ try
+ {
+ // データ検証
+ var validataResult = sharePreBuilddata.DataValidate();
+ if (validataResult.IsFaild())
+ {
+ result.Merge(validataResult);
+ throw new MagicaClothProcessingException();
+ }
+
+ // Deserialize
+ foreach (var sdata in sharePreBuilddata.renderSetupDataList)
+ {
+ renderSetupDataList.Add(RenderSetupData.ShareDeserialize(sdata));
+ }
+ proxyMesh = VirtualMesh.ShareDeserialize(sharePreBuilddata.proxyMesh);
+ foreach (var sdata in sharePreBuilddata.renderMeshList)
+ {
+ renderMeshList.Add(VirtualMesh.ShareDeserialize(sdata));
+ }
+ distanceConstraintData = sharePreBuilddata.distanceConstraintData;
+ bendingConstraintData = sharePreBuilddata.bendingConstraintData;
+ inertiaConstraintData = sharePreBuilddata.inertiaConstraintData;
+
+ result.SetSuccess();
+ }
+ catch (MagicaClothProcessingException)
+ {
+ }
+ catch (Exception exception)
+ {
+ Debug.LogException(exception);
+ result.SetError(Define.Result.Deserialization_Exception);
+ }
+ }
+
+ public int RenderMeshCount => renderMeshList?.Count ?? 0;
+
+ public VirtualMeshContainer GetProxyMeshContainer()
+ {
+ return new VirtualMeshContainer()
+ {
+ shareVirtualMesh = proxyMesh,
+ uniqueData = null,
+ };
+ }
+
+ public VirtualMeshContainer GetRenderMeshContainer(int index)
+ {
+ if (index >= RenderMeshCount)
+ return null;
+
+ return new VirtualMeshContainer()
+ {
+ shareVirtualMesh = renderMeshList[index],
+ uniqueData = null,
+ };
+ }
+ }
+
+ Dictionary deserializationDict = new Dictionary();
+ bool isValid = false;
+
+ //=========================================================================================
+ public void Dispose()
+ {
+ foreach (var kv in deserializationDict)
+ {
+ kv.Value.Dispose();
+ }
+ deserializationDict.Clear();
+
+ isValid = false;
+ }
+
+ public void EnterdEditMode()
+ {
+ Dispose();
+ }
+
+ public void Initialize()
+ {
+ isValid = true;
+ }
+
+ public bool IsValid()
+ {
+ return isValid;
+ }
+
+ public void InformationLog(StringBuilder allsb)
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.AppendLine($"========== PreBuild Manager ==========");
+ if (IsValid() == false)
+ {
+ sb.AppendLine($"PreBuild Manager. Invalid.");
+ }
+ else
+ {
+ int cnt = deserializationDict.Count;
+ sb.AppendLine($"Count:{cnt}");
+
+ foreach (var kv in deserializationDict)
+ {
+ sb.AppendLine($"[{kv.Key.buildId}] refcnt:{kv.Value.referenceCount}, result:{kv.Value.result.GetResultString()}, proxyMesh:{kv.Value.proxyMesh != null}");
+ }
+ }
+
+ sb.AppendLine();
+ Debug.Log(sb.ToString());
+ allsb.Append(sb);
+ }
+
+ //=========================================================================================
+ static readonly ProfilerMarker deserializationProfiler = new ProfilerMarker("PreBuild.Deserialization");
+
+ ///
+ /// PreBuildDataをデシリアライズし登録する
+ /// すでに登録されていた場合は参照カウンタを加算する
+ ///
+ ///
+ ///
+ ///
+ internal ShareDeserializationData RegisterPreBuildData(SharePreBuildData sdata, bool referenceIncrement)
+ {
+ if (isValid == false)
+ return null;
+ if (sdata == null)
+ return null;
+
+ if (deserializationDict.ContainsKey(sdata) == false)
+ {
+ deserializationProfiler.Begin();
+ //var span = new TimeSpan($"Deserialization [{sdata.buildId}]");
+
+ // new
+ var data = new ShareDeserializationData();
+ data.buildId = sdata.buildId;
+
+ data.Deserialize(sdata);
+
+ deserializationDict.Add(sdata, data);
+
+ deserializationProfiler.End();
+ //span.Log();
+
+ Develop.DebugLog($"RegisterPreBuildData.Deserialize [{sdata.buildId}] F:{Time.frameCount}");
+ }
+
+ var ddata = deserializationDict[sdata];
+
+ // reference counter
+ if (referenceIncrement)
+ ddata.referenceCount++;
+
+ Develop.DebugLog($"RegisterPreBuildData [{sdata.buildId}] C:{ddata.referenceCount} F:{Time.frameCount}");
+
+ return ddata;
+ }
+
+ internal ShareDeserializationData GetPreBuildData(SharePreBuildData sdata)
+ {
+ if (sdata == null)
+ return null;
+
+ if (deserializationDict.ContainsKey(sdata))
+ return deserializationDict[sdata];
+
+ return null;
+ }
+
+ ///
+ /// PreBuildDataのデシリアライズデータを解除する
+ /// 参照カウンタが0でも破棄はしない
+ ///
+ ///
+ internal void UnregisterPreBuildData(SharePreBuildData sdata)
+ {
+ if (isValid == false)
+ return;
+ if (sdata == null)
+ return;
+
+ if (deserializationDict.ContainsKey(sdata))
+ {
+ var ddata = deserializationDict[sdata];
+
+ // reference counter
+ ddata.referenceCount--;
+
+ Develop.DebugLog($"UnregisterPreBuildData [{sdata.buildId}] C:{ddata.referenceCount} F:{Time.frameCount}");
+ }
+ else
+ {
+ Develop.DebugLogWarning($"UnregisterPreBuildData not found! [{sdata.buildId}]");
+ }
+ }
+
+ ///
+ /// 未使用のデシリアライズデータをすべて破棄する
+ ///
+ internal void UnloadUnusedData()
+ {
+ var removeKeys = new List();
+
+ foreach (var kv in deserializationDict)
+ {
+ if (kv.Value.referenceCount <= 0)
+ removeKeys.Add(kv.Key);
+ }
+
+ foreach (var key in removeKeys)
+ {
+ var ddata = deserializationDict[key];
+ ddata.Dispose();
+ deserializationDict.Remove(key);
+
+ Develop.DebugLog($"Unload pre-build deserialization data [{key.buildId}] F:{Time.frameCount}");
+ }
+ removeKeys.Clear();
+
+ Develop.DebugLog($"Unload pre-build deserialization data count:{deserializationDict.Count} F:{Time.frameCount}");
+ }
+ }
+}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs.meta
new file mode 100644
index 00000000..44f74b06
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs.meta
@@ -0,0 +1,18 @@
+fileFormatVersion: 2
+guid: 800b8846d5572fe438974d4af951c076
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/Cloth/PreBuildManager.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/IManager.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/IManager.cs.meta
index a05e7923..e6ee31d0 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/IManager.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/IManager.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/IManager.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs
index 03130bd7..a10685fc 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs
@@ -40,6 +40,7 @@ namespace MagicaCloth2
public static SimulationManager Simulation => managers?[6] as SimulationManager;
public static ColliderManager Collider => managers?[7] as ColliderManager;
public static WindManager Wind => managers?[8] as WindManager;
+ public static PreBuildManager PreBuild => managers?[9] as PreBuildManager;
//=========================================================================================
// player loop delegate
@@ -55,6 +56,11 @@ namespace MagicaCloth2
///
public static UpdateMethod afterFixedUpdateDelegate;
+ ///
+ /// PreUpdate()の開始直後
+ ///
+ public static UpdateMethod firstPreUpdateDelegate;
+
///
/// Update()の後
///
@@ -91,8 +97,6 @@ namespace MagicaCloth2
//=========================================================================================
static volatile bool isPlaying = false;
- //static bool isValid = false;
-
//=========================================================================================
///
/// Reload Domain 対策
@@ -122,12 +126,16 @@ namespace MagicaCloth2
managers.Add(new SimulationManager()); // [6]
managers.Add(new ColliderManager()); // [7]
managers.Add(new WindManager()); // [8]
+ managers.Add(new PreBuildManager()); // [9]
foreach (var manager in managers)
manager.Initialize();
// カスタム更新ループ登録
InitCustomGameLoop();
+ // アプリ終了イベント
+ Application.quitting += OnAppQuitting;
+
isPlaying = true;
//isValid = true;
}
@@ -249,6 +257,14 @@ namespace MagicaCloth2
}
#endif
+ ///
+ /// アプリ終了イベント
+ ///
+ static void OnAppQuitting()
+ {
+ Develop.DebugLog($"OnAppQuitting!");
+ Dispose();
+ }
///
/// マネージャの破棄
@@ -267,6 +283,10 @@ namespace MagicaCloth2
// clear static member.
OnPreSimulation = null;
OnPostSimulation = null;
+
+ Application.quitting -= OnAppQuitting;
+
+ isPlaying = false;
}
public static bool IsPlaying()
@@ -321,7 +341,7 @@ namespace MagicaCloth2
type = typeof(MagicaManager),
updateDelegate = () => afterEarlyUpdateDelegate?.Invoke()
};
- AddPlayerLoop(afterEarlyUpdate, ref playerLoop, "EarlyUpdate", string.Empty, last: true);
+ AddPlayerLoop(afterEarlyUpdate, ref playerLoop, "EarlyUpdate", string.Empty, firstLast: 1);
// after fixed update
// FixedUpdate()の後
@@ -335,6 +355,17 @@ namespace MagicaCloth2
};
AddPlayerLoop(afterFixedUpdate, ref playerLoop, "FixedUpdate", "ScriptRunBehaviourFixedUpdate");
+ // first pre update
+ PlayerLoopSystem firstPreUpdate = new PlayerLoopSystem()
+ {
+ type = typeof(MagicaManager),
+ updateDelegate = () =>
+ {
+ firstPreUpdateDelegate?.Invoke();
+ }
+ };
+ AddPlayerLoop(firstPreUpdate, ref playerLoop, "PreUpdate", string.Empty, firstLast: -1);
+
// after update
// Update()の後
PlayerLoopSystem afterUpdate = new PlayerLoopSystem()
@@ -403,13 +434,18 @@ namespace MagicaCloth2
///
///
///
- static void AddPlayerLoop(PlayerLoopSystem method, ref PlayerLoopSystem playerLoop, string categoryName, string systemName, bool last = false, bool before = false)
+ static void AddPlayerLoop(PlayerLoopSystem method, ref PlayerLoopSystem playerLoop, string categoryName, string systemName, int firstLast = 0, bool before = false)
{
int sysIndex = Array.FindIndex(playerLoop.subSystemList, (s) => s.type.Name == categoryName);
PlayerLoopSystem category = playerLoop.subSystemList[sysIndex];
var systemList = new List(category.subSystemList);
- if (last)
+ if (firstLast < 0)
+ {
+ // 最初に追加
+ systemList.Insert(0, method);
+ }
+ else if (firstLast > 0)
{
// 最後に追加
systemList.Add(method);
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs.meta
index 59faaacc..3a72fe73 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManager.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs
index e5fffb44..514ace74 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs
@@ -33,7 +33,6 @@ namespace MagicaCloth2
{
if (IsPlaying())
{
- //Team.globalTimeScale = Mathf.Clamp01(timeScale);
Time.GlobalTimeScale = Mathf.Clamp01(timeScale);
}
}
@@ -47,7 +46,6 @@ namespace MagicaCloth2
{
if (IsPlaying())
{
- //return Team.globalTimeScale;
return Time.GlobalTimeScale;
}
else
@@ -153,5 +151,74 @@ namespace MagicaCloth2
return TimeManager.UpdateLocation.AfterLateUpdate;
}
}
+
+ ///
+ /// 未使用のデータをすべて解放します
+ /// Free all unused data.
+ /// - Unused PreBuild data
+ ///
+ public static void UnloadUnusedData()
+ {
+ if (IsPlaying())
+ {
+ PreBuild.UnloadUnusedData();
+ }
+ }
+
+ ///
+ /// MonoBehaviourでのMagicaClothの初期化場所
+ /// MagicaCloth initialization location in MonoBehaviour.
+ ///
+ public enum InitializationLocation
+ {
+ ///
+ /// Initialize with MonoBehaviour.Start().
+ /// (Default)
+ ///
+ Start = 0,
+
+ ///
+ /// Initialize with MonoBehaviour.Awake().
+ ///
+ Awake = 1,
+ }
+ internal static InitializationLocation initializationLocation = InitializationLocation.Start;
+
+ ///
+ /// MonoBehaviourでのMagicaClothの初期化場所を設定する
+ /// Setting MagicaCloth initialization location in MonoBehaviour.
+ ///
+ ///
+ public static void SetInitializationLocation(InitializationLocation initLocation)
+ {
+ initializationLocation = initLocation;
+ }
+
+ ///
+ /// 分割ジョブを適用するプロキシメッシュの頂点数を設定する
+ /// Sets the number of vertices for the proxy mesh to which the split job will be applied.
+ ///
+ ///
+ public static void SetSplitProxyMeshVertexCount(int vertexCount)
+ {
+ if (IsPlaying())
+ Simulation.splitProxyMeshVertexCount = vertexCount;
+ }
+
+ ///
+ /// 分割ジョブを適用するプロキシメッシュの頂点数を取得する
+ /// Gets the vertex count of the proxy mesh to which the split job is applied.
+ ///
+ ///
+ public static int GetSplitProxyMeshVertexCount()
+ {
+ if (IsPlaying())
+ return Simulation.splitProxyMeshVertexCount;
+ else
+ {
+ Develop.LogError("MagicaManager is not starting!");
+ return 0;
+ }
+ }
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs.meta
index 5cca676a..196e722b 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaManagerAPI.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs
index b99b8060..872f5b40 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs
@@ -15,8 +15,8 @@ namespace MagicaCloth2
public enum RefreshMode
{
///
- /// コンポーネント生成時に1度だけ送信する
- /// Send only once when the component is created.
+ /// コンポーネントのAwake()で1度だけ送信する
+ /// Send once at the component's Awake()
///
OnAwake = 0,
@@ -25,6 +25,18 @@ namespace MagicaCloth2
/// Send content every frame.
///
EveryFrame = 1,
+
+ ///
+ /// コンポーネントのStart()で一度だけ送信する
+ /// Send once at the component's Start().
+ ///
+ OnStart = 2,
+
+ ///
+ /// コンポーネントは何もしません。送信には手動でRefresh()を呼ぶ必要があります
+ /// The component does nothing. You must manually call Refresh() to submit.
+ ///
+ Manual = 3,
}
///
@@ -64,6 +76,12 @@ namespace MagicaCloth2
[Range(Define.System.MaxSimulationCountPerFrame_Low, Define.System.MaxSimulationCountPerFrame_Hi)]
public int maxSimulationCountPerFrame = Define.System.DefaultMaxSimulationCountPerFrame;
+ ///
+ /// MonoBehaviourでのMagicaClothの初期化場所。
+ /// MagicaCloth initialization location in MonoBehaviour.
+ ///
+ public MagicaManager.InitializationLocation initializationLocation = MagicaManager.InitializationLocation.Start;
+
///
/// シミュレーションの更新場所
/// BeforeLateUpdate : LateUpdate()の前に実行します。これはUnity 2D Animationで利用する場合に必要です。
@@ -75,6 +93,27 @@ namespace MagicaCloth2
///
public TimeManager.UpdateLocation updateLocation = TimeManager.UpdateLocation.AfterLateUpdate;
+ ///
+ /// PlayerLoopの監視
+ /// MagicaClothのシステムはUnityのPlayerLoopに登録することで動作します
+ /// この登録が他の外部アセットにより上書きされてしまうと、MagicaClothのシステムが停止してしまいます
+ /// このフラグを有効にすると、PlayerLoopを監視して、上書きされていた場合は再度システムを登録するようになります
+ ///
+ /// PlayerLoop monitoring.
+ /// The MagicaCloth system works by registering it in Unity's PlayerLoop.
+ /// If this registration is overwritten by other external assets, the MagicaCloth system will stop working.
+ /// When this flag is enabled, the PlayerLoop will be monitored, and the system will be registered again if it has been overwritten.
+ ///
+ public bool monitorPlayerLoop = false;
+
+ ///
+ /// ジョブ分割を適用するプロキシメッシュの頂点数
+ ///
+ /// The number of proxy mesh vertices to apply job splitting to.
+ ///
+ [Min(0)]
+ public int splitProxyMeshVertexCount = Define.System.SplitProxyMeshVertexCount;
+
//=========================================================================================
public void Awake()
{
@@ -82,6 +121,12 @@ namespace MagicaCloth2
Refresh();
}
+ public void Start()
+ {
+ if (refreshMode == RefreshMode.OnStart)
+ Refresh();
+ }
+
public void Update()
{
if (refreshMode == RefreshMode.EveryFrame)
@@ -108,7 +153,12 @@ namespace MagicaCloth2
MagicaManager.SetSimulationFrequency(simulationFrequency);
MagicaManager.SetMaxSimulationCountPerFrame(maxSimulationCountPerFrame);
+ MagicaManager.SetInitializationLocation(initializationLocation);
MagicaManager.SetUpdateLocation(updateLocation);
+ MagicaManager.SetSplitProxyMeshVertexCount(splitProxyMeshVertexCount);
+
+ if (monitorPlayerLoop)
+ MagicaManager.InitCustomGameLoop();
}
else
{
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs.meta
index 6c1894e7..09691237 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs.meta
@@ -4,8 +4,15 @@ MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
- executionOrder: 0
+ executionOrder: -50
icon: {fileID: 2800000, guid: 4b0d1adb21ff82e4e8e9ea02f486a85f, type: 3}
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/MagicaSettings.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs
index d5dd0501..31f0de2e 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs
@@ -5,10 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
-using Unity.Burst;
using Unity.Collections;
-using Unity.Jobs;
-using Unity.Mathematics;
using UnityEngine;
namespace MagicaCloth2
@@ -37,6 +34,7 @@ namespace MagicaCloth2
//=========================================================================================
// セットアップデータ
internal RenderSetupData setupData;
+ internal RenderSetupData.UniqueSerializationData preBuildUniqueSerializeData;
internal string Name => setupData?.name ?? "(empty)";
@@ -44,40 +42,27 @@ namespace MagicaCloth2
internal bool HasBoneWeight => setupData?.hasBoneWeight ?? false;
//=========================================================================================
- // カスタムメッシュ情報
- Mesh customMesh;
- NativeArray localPositions;
- NativeArray localNormals;
- NativeArray boneWeights;
- BoneWeight centerBoneWeight;
+ // オリジナル情報
+ internal Mesh originalMesh { get; private set; }
+ private Renderer renderer;
+ private SkinnedMeshRenderer skinnedMeshRendere;
+ private MeshFilter meshFilter;
+ internal List transformList { get; private set; }
+ internal Mesh customMesh { get; private set; }
- ///
- /// カスタムメッシュの使用フラグ
- ///
- public bool UseCustomMesh { get; private set; }
-
- ///
- /// カスタムメッシュの変更フラグ
- ///
- public bool ChangeCustomMesh { get; private set; }
-
- public bool ChangePositionNormal { get; private set; }
- public bool ChangeBoneWeight { get; private set; }
+ // RenderDataWorkバッファへのインデックス(RenderManagerが管理)
+ internal int renderDataWorkIndex { get; private set; } = -1;
//=========================================================================================
public void Dispose()
{
// オリジナルメッシュに戻す
- SwapOriginalMesh();
+ SwapOriginalMesh(null);
setupData?.Dispose();
+ preBuildUniqueSerializeData = null;
- if (localPositions.IsCreated)
- localPositions.Dispose();
- if (localNormals.IsCreated)
- localNormals.Dispose();
- if (boneWeights.IsCreated)
- boneWeights.Dispose();
+ MagicaManager.Render.RemoveRenderDataWork(renderDataWorkIndex);
if (customMesh)
GameObject.Destroy(customMesh);
@@ -98,17 +83,42 @@ namespace MagicaCloth2
/// この処理はスレッド化できないので少し負荷がかかるが即時実行する
///
///
- internal void Initialize(Renderer ren)
+ internal void Initialize(
+ Renderer ren,
+ RenderSetupData referenceSetupData,
+ RenderSetupData.UniqueSerializationData referencePreBuildUniqueSetupData,
+ RenderSetupSerializeData referenceInitSetupData
+ )
{
Debug.Assert(ren);
// セットアップデータ作成
- setupData = new RenderSetupData(ren);
+ // PreBuildでは外部から受け渡される
+ if (referenceSetupData != null && referencePreBuildUniqueSetupData != null)
+ {
+ setupData = referenceSetupData;
+ preBuildUniqueSerializeData = referencePreBuildUniqueSetupData;
- // センタートランスフォーム用ボーンウエイト
- centerBoneWeight = new BoneWeight();
- centerBoneWeight.boneIndex0 = setupData.renderTransformIndex;
- centerBoneWeight.weight0 = 1.0f;
+ originalMesh = preBuildUniqueSerializeData.originalMesh;
+ renderer = preBuildUniqueSerializeData.renderer;
+ skinnedMeshRendere = preBuildUniqueSerializeData.skinRenderer;
+ meshFilter = preBuildUniqueSerializeData.meshFilter;
+ transformList = preBuildUniqueSerializeData.transformList;
+ }
+ else
+ {
+ setupData = new RenderSetupData(referenceInitSetupData, ren);
+ preBuildUniqueSerializeData = null;
+
+ originalMesh = setupData.originalMesh;
+ renderer = setupData.renderer;
+ skinnedMeshRendere = setupData.skinRenderer;
+ meshFilter = setupData.meshFilter;
+ transformList = setupData.transformList;
+ }
+
+ // レンダーデータワークを確保
+ renderDataWorkIndex = MagicaManager.Render.AddRenderDataWork(this);
}
internal ResultCode Result => setupData?.result ?? ResultCode.None;
@@ -127,41 +137,39 @@ namespace MagicaCloth2
}
//=========================================================================================
- void SwapCustomMesh()
+ void SwapCustomMesh(ClothProcess process)
{
Debug.Assert(setupData != null);
if (setupData.IsFaild())
return;
- if (setupData.originalMesh == null)
+ if (originalMesh == null)
+ return;
+ if (MagicaManager.Render.IsSetRenderDataWorkFlag(renderDataWorkIndex, RenderManager.RenderDataFlag_UseCustomMesh))
return;
// カスタムメッシュの作成
if (customMesh == null)
{
- Debug.Assert(setupData.originalMesh);
-
+ //Debug.Assert(setupData.originalMesh);
// クローン作成
- customMesh = GameObject.Instantiate(setupData.originalMesh);
+ customMesh = GameObject.Instantiate(originalMesh);
customMesh.MarkDynamic();
- // 作業配列
- int vertexCount = setupData.vertexCount;
- localPositions = new NativeArray(vertexCount, Allocator.Persistent);
- localNormals = new NativeArray(vertexCount, Allocator.Persistent);
- if (HasBoneWeight)
- boneWeights = new NativeArray(vertexCount, Allocator.Persistent);
-
// bind pose
if (HasBoneWeight)
{
- int transformCount = setupData.TransformCount;
+ int transformCount = preBuildUniqueSerializeData != null ? preBuildUniqueSerializeData.transformList.Count : setupData.TransformCount;
var bindPoseList = new List(transformCount);
bindPoseList.AddRange(setupData.bindPoseList);
// rootBone/skinning bones
while (bindPoseList.Count < transformCount)
bindPoseList.Add(Matrix4x4.identity);
customMesh.bindposes = bindPoseList.ToArray();
+
+ // スキニング用ボーンを書き換える
+ // このリストにはオリジナルのスキニングボーン+レンダラーのトランスフォームが含まれている
+ skinnedMeshRendere.bones = transformList.ToArray();
}
}
@@ -170,45 +178,76 @@ namespace MagicaCloth2
// カスタムメッシュに表示切り替え
SetMesh(customMesh);
+ MagicaManager.Render.SetBitsRenderDataWorkFlag(renderDataWorkIndex, RenderManager.RenderDataFlag_UseCustomMesh, true);
- // スキニング用ボーンを書き換える
- if (HasBoneWeight)
- {
- // このリストにはオリジナルのスキニングボーン+レンダラーのトランスフォームが含まれている
- setupData.skinRenderer.bones = setupData.transformList.ToArray();
- }
-
- UseCustomMesh = true;
+ // Event
+ if (process != null)
+ process.cloth?.OnRendererMeshChange?.Invoke(process.cloth, renderer, true);
}
void ResetCustomMeshWorkData()
{
+ var rm = MagicaManager.Render;
+ ref var wdata = ref rm.GetRenderDataWorkRef(renderDataWorkIndex);
+ int vcnt = setupData.vertexCount;
+
// オリジナルデータをコピーする
- var meshData = setupData.meshDataArray[0];
- meshData.GetVertices(localPositions);
- meshData.GetNormals(localNormals);
- if (HasBoneWeight)
+ if (setupData.HasMeshDataArray)
{
+ var meshData = setupData.meshDataArray[0];
+ using var localPositions = new NativeArray(vcnt, Allocator.TempJob);
+ using var localNormals = new NativeArray(vcnt, Allocator.TempJob);
+ meshData.GetVertices(localPositions);
+ meshData.GetNormals(localNormals);
+ rm.renderMeshPositions.CopyFrom(localPositions, wdata.renderMeshPositionAndNormalChunk.startIndex, vcnt);
+ rm.renderMeshNormals.CopyFrom(localNormals, wdata.renderMeshPositionAndNormalChunk.startIndex, vcnt);
+ if (wdata.HasMeshTangent)
+ {
+ using var localTangents = new NativeArray(vcnt, Allocator.TempJob);
+ meshData.GetTangents(localTangents);
+ rm.renderMeshTangents.CopyFrom(localTangents, wdata.renderMeshTangentChunk.startIndex, vcnt);
+ wdata.flag.SetBits(RenderManager.RenderDataFlag_HasTangent, true); // 最終的な接線あり
+ }
+ }
+ else
+ {
+ rm.renderMeshPositions.CopyFrom(setupData.localPositions, wdata.renderMeshPositionAndNormalChunk.startIndex, vcnt);
+ rm.renderMeshNormals.CopyFrom(setupData.localNormals, wdata.renderMeshPositionAndNormalChunk.startIndex, vcnt);
+ if (wdata.HasMeshTangent && setupData.HasTangent)
+ {
+ rm.renderMeshTangents.CopyFrom(setupData.localTangents, wdata.renderMeshTangentChunk.startIndex, vcnt);
+ wdata.flag.SetBits(RenderManager.RenderDataFlag_HasTangent, true); // 最終的な接線あり
+ }
+ }
+ if (HasBoneWeight && wdata.HasBoneWeight)
+ {
+ using var boneWeights = new NativeArray(vcnt, Allocator.TempJob);
setupData.GetBoneWeightsRun(boneWeights);
+ rm.renderMeshBoneWeights.CopyFrom(boneWeights, wdata.renderMeshBoneWeightChunk.startIndex, vcnt);
}
}
///
/// オリジナルメッシュに戻す
///
- void SwapOriginalMesh()
+ void SwapOriginalMesh(ClothProcess process)
{
- if (UseCustomMesh && setupData != null)
- {
- SetMesh(setupData.originalMesh);
+ var rm = MagicaManager.Render;
- if (setupData.skinRenderer != null)
+ if (rm.IsSetRenderDataWorkFlag(renderDataWorkIndex, RenderManager.RenderDataFlag_UseCustomMesh) && setupData != null)
+ {
+ SetMesh(originalMesh);
+
+ if (skinnedMeshRendere != null)
{
- setupData.skinRenderer.bones = setupData.transformList.ToArray();
+ skinnedMeshRendere.bones = transformList.ToArray();
}
}
+ rm.SetBitsRenderDataWorkFlag(renderDataWorkIndex, RenderManager.RenderDataFlag_UseCustomMesh, false);
- UseCustomMesh = false;
+ // Event
+ if (process != null)
+ process.cloth?.OnRendererMeshChange?.Invoke(process.cloth, renderer, false);
}
///
@@ -222,13 +261,13 @@ namespace MagicaCloth2
if (setupData != null)
{
- if (setupData.meshFilter != null)
+ if (meshFilter != null)
{
- setupData.meshFilter.mesh = mesh;
+ meshFilter.mesh = mesh;
}
- else if (setupData.skinRenderer != null)
+ else if (skinnedMeshRendere != null)
{
- setupData.skinRenderer.sharedMesh = mesh;
+ skinnedMeshRendere.sharedMesh = mesh;
}
}
}
@@ -251,7 +290,7 @@ namespace MagicaCloth2
///
public void EndUse(ClothProcess cprocess)
{
- Debug.Assert(useProcessSet.Count > 0);
+ //Debug.Assert(useProcessSet.Count > 0);
UpdateUse(cprocess, -1);
}
@@ -263,36 +302,62 @@ namespace MagicaCloth2
}
else if (add < 0)
{
- Debug.Assert(useProcessSet.Count > 0);
- useProcessSet.Remove(cprocess);
+ //Debug.Assert(useProcessSet.Count > 0);
+ if (useProcessSet.Contains(cprocess))
+ useProcessSet.Remove(cprocess);
+ else
+ return;
}
// Invisible状態
- bool invisible = useProcessSet.Any(x => x.IsCullingInvisible() && x.IsCullingKeep() == false);
+ bool invisible = useProcessSet.Any(x => (x.IsCameraCullingInvisible() && x.IsCameraCullingKeep() == false) || x.IsDistanceCullingInvisible());
// 状態変更
+ bool modifyBoneWeight = false;
if (invisible || useProcessSet.Count == 0)
{
// 利用停止
// オリジナルメッシュに切り替え
- SwapOriginalMesh();
- ChangeCustomMesh = true;
+ SwapOriginalMesh(cprocess);
}
- else if (useProcessSet.Count == 1)
+ else if (add == 0 && useProcessSet.Count > 0)
+ {
+ // カリング復帰
+ // カスタムメッシュに切り替え、および作業バッファ作成
+ // すでにカスタムメッシュが存在する場合は作業バッファのみ再初期化する
+ SwapCustomMesh(cprocess);
+ modifyBoneWeight = true;
+ }
+ else if (add > 0 && useProcessSet.Count == 1)
{
// 利用開始
// カスタムメッシュに切り替え、および作業バッファ作成
- // すでにカスタムメッシュが存在する場合は作業バッファのみ最初期化する
- SwapCustomMesh();
- ChangeCustomMesh = true;
+ // すでにカスタムメッシュが存在する場合は作業バッファのみ再初期化する
+ SwapCustomMesh(cprocess);
+ modifyBoneWeight = true;
}
else if (add != 0)
{
// 複数から利用されている状態で1つが停止した。
// バッファを最初期化する
ResetCustomMeshWorkData();
- ChangeCustomMesh = true;
+ modifyBoneWeight = true;
}
+
+ // BoneWeight変更を連動するマッピングに指示する
+ if (modifyBoneWeight)
+ {
+ ref var wdata = ref MagicaManager.Render.GetRenderDataWorkRef(renderDataWorkIndex);
+ int mcnt = wdata.mappingDataIndexList.Length;
+ for (int i = 0; i < mcnt; i++)
+ {
+ int mindex = wdata.mappingDataIndexList[i];
+ ref var mdata = ref MagicaManager.Team.GetMappingDataRef(mindex);
+ mdata.flag.SetBits(TeamManager.MappingDataFlag_ModifyBoneWeight, true);
+ }
+ }
+
+ //Debug.Log($"add:{add}, invisible:{invisible}, useCount:{useProcessSet.Count}, ModifyBoneWeight = {flag.IsSet(Flag_ModifyBoneWeight)}");
}
//=========================================================================================
@@ -312,177 +377,39 @@ namespace MagicaCloth2
//=========================================================================================
internal void WriteMesh()
{
- if (UseCustomMesh == false || useProcessSet.Count == 0)
+ var rm = MagicaManager.Render;
+ ref var wdata = ref rm.GetRenderDataWorkRef(renderDataWorkIndex);
+
+ if (wdata.UseCustomMesh == false || useProcessSet.Count == 0)
return;
// 書き込み停止中ならスキップ
if (isSkipWriting)
return;
+ //Debug.Log($"WriteMesh [{Name}] ChangePositionNormal:{flag.IsSet(Flag_ChangePositionNormal)}, ChangeBoneWeight:{flag.IsSet(Flag_ChangeBoneWeight)}");
+
// メッシュに反映
- if (ChangePositionNormal)
+ if (wdata.flag.IsSet(RenderManager.RenderDataFlag_WritePositionNormal))
{
- customMesh.SetVertices(localPositions);
- customMesh.SetNormals(localNormals);
+ customMesh.SetVertices(rm.renderMeshPositions.GetNativeArray(), wdata.renderMeshPositionAndNormalChunk.startIndex, wdata.renderMeshPositionAndNormalChunk.dataLength);
+ customMesh.SetNormals(rm.renderMeshNormals.GetNativeArray(), wdata.renderMeshPositionAndNormalChunk.startIndex, wdata.renderMeshPositionAndNormalChunk.dataLength);
+ wdata.flag.SetBits(RenderManager.RenderDataFlag_WritePositionNormal, false);
+ //Debug.Log($"[{customMesh.name}] Write Position+Normal");
}
- if (ChangeBoneWeight && HasBoneWeight)
+ if (wdata.flag.IsSet(RenderManager.RenderDataFlag_WriteTangent))
{
- customMesh.boneWeights = boneWeights.ToArray();
+ customMesh.SetTangents(rm.renderMeshTangents.GetNativeArray(), wdata.renderMeshTangentChunk.startIndex, wdata.renderMeshTangentChunk.dataLength);
+ wdata.flag.SetBits(RenderManager.RenderDataFlag_WriteTangent, false);
+ //Debug.Log($"[{customMesh.name}] Write Tangent");
}
-
- // 完了
- ChangeCustomMesh = false;
- ChangePositionNormal = false;
- ChangeBoneWeight = false;
- }
-
- //=========================================================================================
- ///
- /// メッシュの位置法線を更新
- ///
- ///
- ///
- ///
- internal JobHandle UpdatePositionNormal(DataChunk mappingChunk, JobHandle jobHandle = default)
- {
- if (UseCustomMesh == false)
- return jobHandle;
-
- var vm = MagicaManager.VMesh;
-
- // 座標・法線の差分書き換え
- var job = new UpdatePositionNormalJob2()
+ if (wdata.flag.IsSet(RenderManager.RenderDataFlag_WriteBoneWeight))
{
- startIndex = mappingChunk.startIndex,
-
- meshLocalPositions = localPositions.Reinterpret(),
- meshLocalNormals = localNormals.Reinterpret(),
-
- mappingReferenceIndices = vm.mappingReferenceIndices.GetNativeArray(),
- mappingAttributes = vm.mappingAttributes.GetNativeArray(),
- mappingPositions = vm.mappingPositions.GetNativeArray(),
- mappingNormals = vm.mappingNormals.GetNativeArray(),
- };
- jobHandle = job.Schedule(mappingChunk.dataLength, 32, jobHandle);
-
- ChangePositionNormal = true;
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct UpdatePositionNormalJob2 : IJobParallelFor
- {
- public int startIndex;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray meshLocalPositions;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray meshLocalNormals;
-
- // mapping mesh
- [Unity.Collections.ReadOnly]
- public NativeArray mappingReferenceIndices;
- [Unity.Collections.ReadOnly]
- public NativeArray mappingAttributes;
- [Unity.Collections.ReadOnly]
- public NativeArray mappingPositions;
- [Unity.Collections.ReadOnly]
- public NativeArray mappingNormals;
-
- public void Execute(int index)
- {
- int vindex = index + startIndex;
-
- // 無効頂点なら書き込まない
- var attr = mappingAttributes[vindex];
- if (attr.IsInvalid())
- return;
-
- // 固定も書き込まない(todo:一旦こうする)
- if (attr.IsFixed())
- return;
-
- // 書き込む頂点インデックス
- int windex = mappingReferenceIndices[vindex];
-
- // 座標書き込み
- meshLocalPositions[windex] = mappingPositions[vindex];
-
- // 法線書き込み
- meshLocalNormals[windex] = mappingNormals[vindex];
- }
- }
-
- ///
- /// メッシュのボーンウエイト書き込み
- ///
- ///
- ///
- ///
- internal JobHandle UpdateBoneWeight(DataChunk mappingChunk, JobHandle jobHandle = default)
- {
- if (UseCustomMesh == false)
- return jobHandle;
-
- // ボーンウエイトの差分書き換え
- if (HasBoneWeight)
- {
- var vm = MagicaManager.VMesh;
-
- var job = new UpdateBoneWeightJob2()
- {
- startIndex = mappingChunk.startIndex,
- centerBoneWeight = centerBoneWeight,
- meshBoneWeights = boneWeights,
-
- mappingReferenceIndices = vm.mappingReferenceIndices.GetNativeArray(),
- mappingAttributes = vm.mappingAttributes.GetNativeArray(),
- };
- jobHandle = job.Schedule(mappingChunk.dataLength, 32, jobHandle);
-
- ChangeBoneWeight = true;
- }
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct UpdateBoneWeightJob2 : IJobParallelFor
- {
- public int startIndex;
- public BoneWeight centerBoneWeight;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray meshBoneWeights;
-
- // mapping mesh
- [Unity.Collections.ReadOnly]
- public NativeArray mappingReferenceIndices;
- [Unity.Collections.ReadOnly]
- public NativeArray mappingAttributes;
-
- public void Execute(int index)
- {
- int vindex = index + startIndex;
-
- // 無効頂点なら書き込まない
- var attr = mappingAttributes[vindex];
- if (attr.IsInvalid())
- return;
-
- // 固定も書き込まない(todo:一旦こうする)
- if (attr.IsFixed())
- return;
-
- // 書き込む頂点インデックス
- int windex = mappingReferenceIndices[vindex];
-
- // 使用頂点のウエイトはcenterTransform100%で書き込む
- meshBoneWeights[windex] = centerBoneWeight;
+ // BoneWeightはNativeArrayの区間指定ができない
+ var boneWeightsSlice = new NativeSlice(rm.renderMeshBoneWeights.GetNativeArray(), wdata.renderMeshBoneWeightChunk.startIndex, wdata.renderMeshBoneWeightChunk.dataLength);
+ customMesh.boneWeights = boneWeightsSlice.ToArray();
+ wdata.flag.SetBits(RenderManager.RenderDataFlag_WriteBoneWeight, false);
+ //Debug.Log($"[{customMesh.name}] Write BoneWeight");
}
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs.meta
index ba4428ef..14eff1e6 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderData.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs
index 0bfc9373..8572bffc 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs
@@ -3,6 +3,9 @@
// https://magicasoft.jp
using System.Collections.Generic;
using System.Text;
+using Unity.Collections;
+using Unity.Mathematics;
+using Unity.Profiling;
using UnityEngine;
namespace MagicaCloth2
@@ -17,6 +20,78 @@ namespace MagicaCloth2
///
Dictionary renderDataDict = new Dictionary();
+ //=========================================================================================
+ // ■RenderData
+ //=========================================================================================
+ ///
+ /// RenderDataの状態フラグ(32bit)
+ ///
+ public const int RenderDataFlag_UseCustomMesh = 0; // カスタムメッシュの利用
+ public const int RenderDataFlag_WritePositionNormal = 1; // 座標および法線の書き込み
+ public const int RenderDataFlag_WriteBoneWeight = 2; // ボーンウエイトの書き込み
+ //public const int RenderDataFlag_ModifyBoneWeight = 3; // ボーンウエイトの変更
+ public const int RenderDataFlag_HasMeshTangent = 4; // オリジナルメッシュが接線を持っているかどうか
+ public const int RenderDataFlag_HasTangent = 5; // 最終的に接線情報を持っているかどうか
+ public const int RenderDataFlag_WriteTangent = 6; // 接線の書き込み
+ public const int RenderDataFlag_HasSkinnedMesh = 7;
+ public const int RenderDataFlag_HasBoneWeight = 8;
+
+ public struct RenderDataWork : IValid
+ {
+ ///
+ /// RenderData状態フラグ
+ ///
+ public BitField32 flag;
+
+ ///
+ /// バッファへの格納先情報
+ ///
+ public DataChunk renderMeshPositionAndNormalChunk;
+ public DataChunk renderMeshTangentChunk;
+ public DataChunk renderMeshBoneWeightChunk;
+
+ ///
+ /// 制御頂点に設定するボーンウエイト
+ ///
+ public BoneWeight centerBoneWeight;
+
+ ///
+ /// 紐づけられているマッピングメッシュデータへのインデックスリスト
+ ///
+ public FixedList32Bytes mappingDataIndexList;
+
+ public bool IsValid()
+ {
+ return renderMeshPositionAndNormalChunk.IsValid;
+ }
+
+ public bool UseCustomMesh => flag.IsSet(RenderDataFlag_UseCustomMesh);
+ public bool HasMeshTangent => flag.IsSet(RenderDataFlag_HasMeshTangent);
+ public bool HasTangent => flag.IsSet(RenderDataFlag_HasTangent);
+ public bool HasBoneWeight => flag.IsSet(RenderDataFlag_HasBoneWeight);
+
+ public void AddMappingIndex(int mindex)
+ {
+ mappingDataIndexList.Add((short)mindex);
+ }
+
+ public void RemoveMappingIndex(int mindex)
+ {
+ mappingDataIndexList.MC2RemoveItemAtSwapBack((short)mindex);
+ }
+ }
+ public ExNativeArray renderDataWorkArray;
+
+ public int RenderDataWorkCount => renderDataWorkArray?.Count ?? 0;
+
+ //=========================================================================================
+ // ■RenderMesh
+ //=========================================================================================
+ public ExNativeArray renderMeshPositions;
+ public ExNativeArray renderMeshNormals;
+ public ExNativeArray renderMeshTangents;
+ public ExNativeArray renderMeshBoneWeights;
+
bool isValid = false;
//=========================================================================================
@@ -24,6 +99,15 @@ namespace MagicaCloth2
{
Dispose();
+ // 作業バッファ
+ const int capacity = 0;
+ const bool create = true;
+ renderDataWorkArray = new ExNativeArray(capacity, create);
+ renderMeshPositions = new ExNativeArray(capacity, create);
+ renderMeshNormals = new ExNativeArray(capacity, create);
+ renderMeshTangents = new ExNativeArray(capacity, create);
+ renderMeshBoneWeights = new ExNativeArray(capacity, create);
+
// 更新処理
MagicaManager.afterDelayedDelegate += PreRenderingUpdate;
@@ -48,6 +132,18 @@ namespace MagicaCloth2
}
renderDataDict.Clear();
+ // 作業バッファ
+ renderDataWorkArray?.Dispose();
+ renderMeshPositions?.Dispose();
+ renderMeshNormals?.Dispose();
+ renderMeshTangents?.Dispose();
+ renderMeshBoneWeights?.Dispose();
+ renderDataWorkArray = null;
+ renderMeshPositions = null;
+ renderMeshNormals = null;
+ renderMeshBoneWeights = null;
+ renderMeshTangents = null;
+
// 更新処理
MagicaManager.afterDelayedDelegate -= PreRenderingUpdate;
}
@@ -63,7 +159,12 @@ namespace MagicaCloth2
///
///
///
- public int AddRenderer(Renderer ren)
+ public int AddRenderer(
+ Renderer ren,
+ RenderSetupData referenceSetupData,
+ RenderSetupData.UniqueSerializationData referenceUniqueSetupData,
+ RenderSetupSerializeData referenceInitSetupData
+ )
{
if (isValid == false)
return 0;
@@ -78,7 +179,7 @@ namespace MagicaCloth2
{
// 新規
var rdata = new RenderData();
- rdata.Initialize(ren);
+ rdata.Initialize(ren, referenceSetupData, referenceUniqueSetupData, referenceInitSetupData);
renderDataDict.Add(handle, rdata);
}
@@ -96,8 +197,6 @@ namespace MagicaCloth2
bool delete = false;
- //if(renderDataDict.ContainsKey(handle) == )
-
//Debug.Log($"RemoveRenderer:{handle}");
//Debug.Assert(ren);
Debug.Assert(renderDataDict.ContainsKey(handle));
@@ -137,6 +236,92 @@ namespace MagicaCloth2
}
}
+ //=========================================================================================
+ public int AddRenderDataWork(RenderData rdata)
+ {
+ if (isValid == false)
+ return -1;
+
+ var wdata = new RenderDataWork();
+
+ // オリジナルメッシュの接線情報を確認
+ wdata.flag.SetBits(RenderDataFlag_HasMeshTangent, rdata.originalMesh.HasVertexAttribute(UnityEngine.Rendering.VertexAttribute.Tangent));
+ //Debug.Log($"OriginalMesh[{originalMesh.name}] hasTangent:{originalMesh.HasVertexAttribute(UnityEngine.Rendering.VertexAttribute.Tangent)}");
+
+ // Flag
+ wdata.flag.SetBits(RenderDataFlag_HasSkinnedMesh, rdata.HasSkinnedMesh);
+ wdata.flag.SetBits(RenderDataFlag_HasBoneWeight, rdata.HasBoneWeight);
+
+ // センタートランスフォーム用ボーンウエイト
+ var centerBoneWeight = new BoneWeight();
+ centerBoneWeight.boneIndex0 = rdata.setupData.renderTransformIndex;
+ centerBoneWeight.weight0 = 1.0f;
+ wdata.centerBoneWeight = centerBoneWeight;
+
+ // レンダーメッシュ用バッファ確保
+ int vcnt = rdata.originalMesh.vertexCount;
+ wdata.renderMeshPositionAndNormalChunk = renderMeshPositions.AddRange(vcnt);
+ renderMeshNormals.AddRange(vcnt);
+ if (wdata.HasMeshTangent)
+ wdata.renderMeshTangentChunk = renderMeshTangents.AddRange(vcnt);
+ if (wdata.HasBoneWeight)
+ {
+ wdata.renderMeshBoneWeightChunk = renderMeshBoneWeights.AddRange(vcnt);
+ }
+
+ // 格納
+ var c = renderDataWorkArray.Add(wdata);
+ return c.startIndex;
+ }
+
+ public void RemoveRenderDataWork(int index)
+ {
+ if (isValid == false)
+ return;
+ if (index < 0)
+ return;
+
+ // バッファ削除
+ ref var wdata = ref GetRenderDataWorkRef(index);
+ if (wdata.renderMeshPositionAndNormalChunk.IsValid)
+ {
+ renderMeshPositions.Remove(wdata.renderMeshPositionAndNormalChunk);
+ renderMeshNormals.Remove(wdata.renderMeshPositionAndNormalChunk);
+ }
+ if (wdata.renderMeshTangentChunk.IsValid)
+ {
+ renderMeshTangents.Remove(wdata.renderMeshTangentChunk);
+ }
+ if (wdata.renderMeshBoneWeightChunk.IsValid)
+ {
+ renderMeshBoneWeights.Remove(wdata.renderMeshBoneWeightChunk);
+ }
+ wdata.renderMeshPositionAndNormalChunk.Clear();
+ wdata.renderMeshTangentChunk.Clear();
+ wdata.renderMeshBoneWeightChunk.Clear();
+ wdata.flag.Clear();
+
+ // 削除
+ renderDataWorkArray.RemoveAndFill(new DataChunk(index));
+ }
+
+ public ref RenderDataWork GetRenderDataWorkRef(int index)
+ {
+ return ref renderDataWorkArray.GetRef(index);
+ }
+
+ public bool IsSetRenderDataWorkFlag(int index, int flag)
+ {
+ ref var wdata = ref GetRenderDataWorkRef(index);
+ return wdata.flag.IsSet(flag);
+ }
+
+ public void SetBitsRenderDataWorkFlag(int index, int flag, bool sw)
+ {
+ ref var wdata = ref GetRenderDataWorkRef(index);
+ wdata.flag.SetBits(flag, sw);
+ }
+
//=========================================================================================
///
/// 有効化
@@ -157,14 +342,21 @@ namespace MagicaCloth2
}
//=========================================================================================
+ static readonly ProfilerMarker writeMeshTimeProfiler = new ProfilerMarker("WriteMesh");
+
///
/// レンダリング前更新
///
void PreRenderingUpdate()
{
+ if (renderDataDict.Count == 0)
+ return;
+
// メッシュへの反映
+ writeMeshTimeProfiler.Begin();
foreach (var rdata in renderDataDict.Values)
rdata?.WriteMesh();
+ writeMeshTimeProfiler.End();
}
//=========================================================================================
@@ -179,7 +371,25 @@ namespace MagicaCloth2
else
{
sb.AppendLine($"Render Manager. Count({renderDataDict.Count})");
+ sb.AppendLine($" [RenderMeshBuffer]");
+ sb.AppendLine($" -renderMeshPositions:{renderMeshPositions.ToSummary()}");
+ sb.AppendLine($" -renderMeshNormals:{renderMeshNormals.ToSummary()}");
+ sb.AppendLine($" -renderMeshTangents:{renderMeshTangents.ToSummary()}");
+ sb.AppendLine($" [RenderDataWork]");
+ sb.AppendLine($" -Count:{renderDataWorkArray.Count}");
+ if (renderDataWorkArray.Count > 0)
+ {
+ for (int j = 0; j < renderDataWorkArray.Count; j++)
+ {
+ var wdata = renderDataWorkArray[j];
+ if (wdata.IsValid() == false)
+ continue;
+ sb.AppendLine($" [{j}] MappingListCount:{wdata.mappingDataIndexList.Length}");
+ }
+ }
+
+ sb.AppendLine($" [RenderData]");
foreach (var kv in renderDataDict)
{
sb.Append(kv.Value.ToString());
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs.meta
index f3368aa8..b40fe674 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderManager.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs
index 948d41c3..0a7821a1 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs
@@ -7,6 +7,7 @@ using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
+using Unity.Profiling;
using UnityEngine;
using UnityEngine.Jobs;
@@ -19,10 +20,11 @@ namespace MagicaCloth2
/// またこの情報はキャラクターが動き出す前に取得しておく必要がある
/// そのためAwake()などで実行する
///
- public class RenderSetupData : IDisposable, ITransform
+ public partial class RenderSetupData : IDisposable, ITransform
{
public ResultCode result;
public string name = string.Empty;
+ public bool isManaged; // pre-build DeserializeManager管理
// タイプ
public enum SetupType
@@ -45,11 +47,17 @@ namespace MagicaCloth2
public Mesh.MeshDataArray meshDataArray; // Jobで利用するためのMeshData
public int skinRootBoneIndex;
public int skinBoneCount;
+
// MeshDataでは取得できないメッシュ情報
public List bindPoseList;
public NativeArray bonesPerVertexArray;
public NativeArray boneWeightArray;
+ // PreBuild時のみ保持する情報.逆にmeshDataArrayは持たない
+ public NativeArray localPositions;
+ public NativeArray localNormals;
+ public NativeArray localTangents;
+
// Bone ---------------------------------------------------------------
public List rootTransformIdList;
public enum BoneConnectionMode
@@ -82,7 +90,7 @@ namespace MagicaCloth2
public List> transformChildIdList; // 子IDリスト
public NativeArray transformPositions;
public NativeArray transformRotations;
- public NativeArray transformLocalPositins;
+ public NativeArray transformLocalPositions;
public NativeArray transformLocalRotations;
public NativeArray transformScales;
public NativeArray transformInverseRotations;
@@ -95,16 +103,21 @@ namespace MagicaCloth2
public bool IsSuccess() => result.IsSuccess();
public bool IsFaild() => result.IsFaild();
public int TransformCount => transformList?.Count ?? 0;
+ public bool HasMeshDataArray => meshDataArray.Length > 0;
+ public bool HasLocalPositions => localPositions.IsCreated;
+ public bool HasTangent => localTangents.IsCreated && localTangents.Length > 0;
- //static readonly ProfilerMarker initProfiler = new ProfilerMarker("Render Setup");
+ static readonly ProfilerMarker readTransformProfiler = new ProfilerMarker("readTransform");
//=========================================================================================
+ public RenderSetupData() { }
+
///
/// レンダラーから基本情報を作成する(メインスレッドのみ)
/// タイプはMeshになる
///
///
- public RenderSetupData(Renderer ren)
+ public RenderSetupData(RenderSetupSerializeData referenceInitSetupData, Renderer ren)
{
//using (initProfiler.Auto())
{
@@ -119,6 +132,9 @@ namespace MagicaCloth2
return;
}
+ // 初期化データの有無
+ bool useInitData = referenceInitSetupData != null;
+
name = ren.name;
var sren = ren as SkinnedMeshRenderer;
@@ -133,7 +149,36 @@ namespace MagicaCloth2
// 描画の基準トランスフォーム
var renderTransform = ren.transform;
- if (sren)
+ if (useInitData)
+ {
+ // 初期化データがある場合はコピーして終わり
+ skinBoneCount = referenceInitSetupData.skinBoneCount;
+ skinRootBoneIndex = referenceInitSetupData.skinRootBoneIndex;
+ renderTransformIndex = referenceInitSetupData.renderTransformIndex;
+ hasBoneWeight = referenceInitSetupData.hasBoneWeight;
+
+ // transformList復元
+ transformList = new List(new Transform[referenceInitSetupData.transformCount]);
+ int ucnt = referenceInitSetupData.useTransformCount;
+ for (int i = 0; i < ucnt; i++)
+ {
+ int tindex = referenceInitSetupData.useTransformIndexArray[i];
+ transformList[tindex] = referenceInitSetupData.transformArray[i];
+ }
+
+ // SkinnedMeshRendererかつオリジナルメッシュが存在する場合はSkinnedMeshRenererを復元する
+ // 実行時キャラクターコピーへの対応
+ if (sren && referenceInitSetupData.originalMesh && sren.sharedMesh != referenceInitSetupData.originalMesh && skinBoneCount > 0)
+ {
+ sren.sharedMesh = referenceInitSetupData.originalMesh;
+ var newBones = new Transform[skinBoneCount];
+ transformList.CopyTo(0, newBones, 0, skinBoneCount);
+ sren.bones = newBones;
+ sren.rootBone = transformList[skinRootBoneIndex];
+ //Debug.Log($"★SkinnedMeshRenderer再構成");
+ }
+ }
+ else if (sren)
{
// bones
// このスキニングボーンの取得が特に重くメモリアロケーションも頻発する問題児
@@ -188,7 +233,7 @@ namespace MagicaCloth2
}
// トランスフォーム情報の読み取り
- ReadTransformInformation(includeChilds: false);
+ ReadTransformInformation(includeChilds: false, referenceInitSetupData, ren.transform);
// bindpose / weights
if (sren)
@@ -207,12 +252,14 @@ namespace MagicaCloth2
// どうもコピーを作らないとダメらしい..
// ※具体的にはメッシュのクローンを作成したときに壊れる
- var weightArray = mesh.GetAllBoneWeights();
- var perVertexArray = mesh.GetBonesPerVertex();
+ using var weightArray = mesh.GetAllBoneWeights();
+ using var perVertexArray = mesh.GetBonesPerVertex();
boneWeightArray = new NativeArray(weightArray, Allocator.Persistent);
bonesPerVertexArray = new NativeArray(perVertexArray, Allocator.Persistent);
+#if UNITY_EDITOR
// 5ボーン以上を利用する頂点ウエイトは警告とする。一応無効となるだけで動くのでエラーにはしない。
+ // なおこの検証はビルド環境では行わない
int vcnt = mesh.vertexCount;
using var bonesPerVertexResult = new NativeReference(Allocator.TempJob);
var job = new VertexWeight5BoneCheckJob()
@@ -223,6 +270,7 @@ namespace MagicaCloth2
};
job.Run();
result.SetWarning(bonesPerVertexResult.Value);
+#endif
}
else
{
@@ -276,6 +324,10 @@ namespace MagicaCloth2
}
}
+#if UNITY_EDITOR
+ ///
+ /// 5ウエイト以上の検出
+ ///
[BurstCompile]
struct VertexWeight5BoneCheckJob : IJob
{
@@ -301,6 +353,7 @@ namespace MagicaCloth2
}
}
}
+#endif
///
/// ルートボーンリストから基本情報を作成する(メインスレッドのみ)
@@ -309,6 +362,7 @@ namespace MagicaCloth2
///
///
public RenderSetupData(
+ RenderSetupSerializeData referenceInitSetupData,
SetupType setType,
Transform renderTransform,
List rootTransforms,
@@ -322,6 +376,8 @@ namespace MagicaCloth2
//using (initProfiler.Auto())
try
{
+ bool useInitData = referenceInitSetupData != null;
+
// Boneタイプに設定
setupType = setType;
@@ -344,30 +400,47 @@ namespace MagicaCloth2
this.name = name;
// 必要なトランスフォーム情報
- var indexDict = new Dictionary(256);
- transformList = new List(256);
-
- // root以下をすべて登録する
- var stack = new Stack(256);
- foreach (var t in rootTransforms)
- stack.Push(t);
- while (stack.Count > 0)
+ if (useInitData)
{
- var t = stack.Pop();
- if (indexDict.ContainsKey(t))
- continue;
+ // 初期化データがある場合はコピーして終わり
+ transformList = new List(referenceInitSetupData.transformArray);
+ skinBoneCount = referenceInitSetupData.skinBoneCount;
+ renderTransformIndex = referenceInitSetupData.renderTransformIndex;
+ }
+ else
+ {
+ var indexDict = new Dictionary(256);
+ transformList = new List(256);
- // 登録
- int index = transformList.Count;
- transformList.Add(t);
- indexDict.Add(t, index);
-
- // child
- int cnt = t.childCount;
- for (int i = 0; i < cnt; i++)
+ // root以下をすべて登録する
+ var stack = new Stack(256);
+ foreach (var t in rootTransforms)
+ stack.Push(t);
+ while (stack.Count > 0)
{
- stack.Push(t.GetChild(i));
+ var t = stack.Pop();
+ if (indexDict.ContainsKey(t))
+ continue;
+
+ // 登録
+ int index = transformList.Count;
+ transformList.Add(t);
+ indexDict.Add(t, index);
+
+ // child
+ int cnt = t.childCount;
+ for (int i = 0; i < cnt; i++)
+ {
+ stack.Push(t.GetChild(i));
+ }
}
+
+ // スキニングボーン数
+ skinBoneCount = transformList.Count;
+
+ // レンダートランスフォームを最後に追加
+ renderTransformIndex = transformList.Count;
+ transformList.Add(renderTransform);
}
// root transform id
@@ -392,15 +465,8 @@ namespace MagicaCloth2
}
}
- // スキニングボーン数
- skinBoneCount = transformList.Count;
-
- // レンダートランスフォームを最後に追加
- renderTransformIndex = transformList.Count;
- transformList.Add(renderTransform);
-
// トランスフォーム情報の読み取り
- ReadTransformInformation(includeChilds: true);
+ ReadTransformInformation(includeChilds: true, referenceInitSetupData, renderTransform);
// 完了
result.SetSuccess();
@@ -422,42 +488,117 @@ namespace MagicaCloth2
/// トランスフォーム情報の読み取り(メインスレッドのみ)
/// この情報だけはキャラクターが動く前に取得する必要がある
///
- void ReadTransformInformation(bool includeChilds)
+ void ReadTransformInformation(bool includeChilds, RenderSetupSerializeData referenceInitSetupData, Transform rendererTransform)
{
+ readTransformProfiler.Begin();
+
int tcnt = transformList.Count;
- using var transformArray = new TransformAccessArray(transformList.ToArray());
+ bool useInitData = referenceInitSetupData != null;
+
+ // バッファ作成
transformPositions = new NativeArray(tcnt, Allocator.Persistent);
transformRotations = new NativeArray(tcnt, Allocator.Persistent);
- transformLocalPositins = new NativeArray(tcnt, Allocator.Persistent);
+ transformLocalPositions = new NativeArray(tcnt, Allocator.Persistent);
transformLocalRotations = new NativeArray(tcnt, Allocator.Persistent);
transformScales = new NativeArray(tcnt, Allocator.Persistent);
transformInverseRotations = new NativeArray(tcnt, Allocator.Persistent);
- var job = new ReadTransformJob()
+
+ // 読み取り
+ if (useInitData)
{
- positions = transformPositions,
- rotations = transformRotations,
- scales = transformScales,
- localPositions = transformLocalPositins,
- localRotations = transformLocalRotations,
- inverseRotations = transformInverseRotations,
- };
- // シミュレーション以外でワーカーを消費したくないのでRun()版にしておく
- job.RunReadOnly(transformArray);
+ Debug.Assert(tcnt == referenceInitSetupData.transformCount);
- // 初期センタートランスフォームを別途コピーしておく
- initRenderLocalToWorld = GetRendeerLocalToWorldMatrix();
- initRenderWorldtoLocal = math.inverse(initRenderLocalToWorld);
- initRenderRotation = transformRotations[renderTransformIndex];
- initRenderScale = transformScales[renderTransformIndex];
+ // 初期化データがある場合はコピーして終わり
+ int ucnt = referenceInitSetupData.useTransformCount;
- // id
+ if (ucnt == tcnt)
+ {
+ // 全体コピー
+ NativeArray.Copy(referenceInitSetupData.transformPositions, 0, transformPositions, 0, ucnt);
+ NativeArray.Copy(referenceInitSetupData.transformRotations, 0, transformRotations, 0, ucnt);
+ NativeArray.Copy(referenceInitSetupData.transformLocalPositions, 0, transformLocalPositions, 0, ucnt);
+ NativeArray.Copy(referenceInitSetupData.transformLocalRotations, 0, transformLocalRotations, 0, ucnt);
+ NativeArray.Copy(referenceInitSetupData.transformScales, 0, transformScales, 0, ucnt);
+ }
+ else
+ {
+ // 差分
+ for (int i = 0; i < ucnt; i++)
+ {
+ int tindex = referenceInitSetupData.useTransformIndexArray[i];
+ transformPositions[tindex] = referenceInitSetupData.transformPositions[i];
+ transformRotations[tindex] = referenceInitSetupData.transformRotations[i];
+ transformLocalPositions[tindex] = referenceInitSetupData.transformLocalPositions[i];
+ transformLocalRotations[tindex] = referenceInitSetupData.transformLocalRotations[i];
+ transformScales[tindex] = referenceInitSetupData.transformScales[i];
+ }
+ }
+
+ // 逆回転のみ計算で求める
+ var job = new CalcInverseRotationJob()
+ {
+ rotations = transformRotations,
+ inverseRotations = transformInverseRotations,
+ };
+ job.Run(tcnt);
+
+ // 初期センタートランスフォームを別途コピーしておく
+ initRenderLocalToWorld = referenceInitSetupData.initRenderLocalToWorld;
+ initRenderWorldtoLocal = referenceInitSetupData.initRenderWorldtoLocal;
+ initRenderRotation = referenceInitSetupData.initRenderRotation;
+ initRenderScale = referenceInitSetupData.initRenderScale;
+ }
+ else
+ {
+ //using var transformArray = new TransformAccessArray(transformList.ToArray());
+ // Unity6.1対応
+ using var transformArray = new TransformAccessArray(transformList.Count);
+ int cnt = transformList.Count;
+ for (int i = 0; i < cnt; i++)
+ {
+ var t = transformList[i];
+ if (t == null)
+ t = rendererTransform;
+ //transformArray[i] = t;
+ transformArray.Add(t);
+ }
+
+
+ var job = new ReadTransformJob()
+ {
+ positions = transformPositions,
+ rotations = transformRotations,
+ scales = transformScales,
+ localPositions = transformLocalPositions,
+ localRotations = transformLocalRotations,
+ inverseRotations = transformInverseRotations
+ };
+ // シミュレーション以外でワーカーを消費したくないのでRun()版にしておく
+ job.RunReadOnly(transformArray);
+
+ // 初期センタートランスフォームを別途コピーしておく
+ initRenderLocalToWorld = GetRendeerLocalToWorldMatrix();
+ initRenderWorldtoLocal = math.inverse(initRenderLocalToWorld);
+ initRenderRotation = transformRotations[renderTransformIndex];
+ initRenderScale = transformScales[renderTransformIndex];
+ }
+
+ // id / parent id
transformIdList = new List(tcnt);
transformParentIdList = new List(tcnt);
for (int i = 0; i < tcnt; i++)
{
+ int id = 0, pid = 0;
+
var t = transformList[i];
- transformIdList.Add(t?.GetInstanceID() ?? 0);
- transformParentIdList.Add(t?.parent?.GetInstanceID() ?? 0);
+ if (t)
+ {
+ id = t.GetInstanceID();
+ if (includeChilds && t.parent)
+ pid = t.parent.GetInstanceID();
+ }
+ transformIdList.Add(id);
+ transformParentIdList.Add(pid);
}
// child id
@@ -468,7 +609,7 @@ namespace MagicaCloth2
{
var t = transformList[i];
var clist = new FixedList512Bytes();
- if (t?.childCount > 0)
+ if (t && t.childCount > 0)
{
for (int j = 0; j < t.childCount; j++)
{
@@ -479,6 +620,32 @@ namespace MagicaCloth2
transformChildIdList.Add(clist);
}
}
+
+ readTransformProfiler.End();
+ }
+
+ ///
+ /// 逆回転を計算で求める
+ ///
+ [BurstCompile]
+ struct CalcInverseRotationJob : IJobParallelFor
+ {
+ [Unity.Collections.ReadOnly]
+ public NativeArray rotations;
+ [NativeDisableParallelForRestriction]
+ [Unity.Collections.WriteOnly]
+ public NativeArray inverseRotations;
+
+ public void Execute(int index)
+ {
+ var rot = rotations[index];
+ if (math.any(rot.value))
+ {
+ // どれか1つでも != 0 なら実行する
+ var irot = math.inverse(rot);
+ inverseRotations[index] = irot;
+ }
+ }
}
///
@@ -487,16 +654,22 @@ namespace MagicaCloth2
[BurstCompile]
struct ReadTransformJob : IJobParallelForTransform
{
+ [NativeDisableParallelForRestriction]
[Unity.Collections.WriteOnly]
public NativeArray positions;
+ [NativeDisableParallelForRestriction]
[Unity.Collections.WriteOnly]
public NativeArray rotations;
+ [NativeDisableParallelForRestriction]
[Unity.Collections.WriteOnly]
public NativeArray scales;
+ [NativeDisableParallelForRestriction]
[Unity.Collections.WriteOnly]
public NativeArray localPositions;
+ [NativeDisableParallelForRestriction]
[Unity.Collections.WriteOnly]
public NativeArray localRotations;
+ [NativeDisableParallelForRestriction]
[Unity.Collections.WriteOnly]
public NativeArray inverseRotations;
@@ -527,23 +700,22 @@ namespace MagicaCloth2
public void Dispose()
{
- if (bonesPerVertexArray.IsCreated)
- bonesPerVertexArray.Dispose();
- if (boneWeightArray.IsCreated)
- boneWeightArray.Dispose();
+ // Pre-Build DeserializeManager管理中は破棄させない
+ if (isManaged)
+ return;
- if (transformPositions.IsCreated)
- transformPositions.Dispose();
- if (transformRotations.IsCreated)
- transformRotations.Dispose();
- if (transformLocalPositins.IsCreated)
- transformLocalPositins.Dispose();
- if (transformLocalRotations.IsCreated)
- transformLocalRotations.Dispose();
- if (transformScales.IsCreated)
- transformScales.Dispose();
- if (transformInverseRotations.IsCreated)
- transformInverseRotations.Dispose();
+ bonesPerVertexArray.MC2DisposeSafe();
+ boneWeightArray.MC2DisposeSafe();
+ localPositions.MC2DisposeSafe();
+ localNormals.MC2DisposeSafe();
+ localTangents.MC2DisposeSafe();
+
+ transformPositions.MC2DisposeSafe();
+ transformRotations.MC2DisposeSafe();
+ transformLocalPositions.MC2DisposeSafe();
+ transformLocalRotations.MC2DisposeSafe();
+ transformScales.MC2DisposeSafe();
+ transformInverseRotations.MC2DisposeSafe();
// MeshDataArrayはメインスレッドのみDispose()可能
if (setupType == SetupType.MeshCloth)
@@ -555,8 +727,12 @@ namespace MagicaCloth2
public void GetUsedTransform(HashSet transformSet)
{
- foreach (var t in transformList)
- transformSet.Add(t);
+ if (transformList != null)
+ {
+ foreach (var t in transformList)
+ if (t)
+ transformSet.Add(t);
+ }
}
public void ReplaceTransform(Dictionary replaceDict)
@@ -622,9 +798,10 @@ namespace MagicaCloth2
public float4x4 GetRendeerLocalToWorldMatrix()
{
- var pos = transformPositions[renderTransformIndex];
- var rot = transformRotations[renderTransformIndex];
- var scl = transformScales[renderTransformIndex];
+ int index = renderTransformIndex;
+ var pos = transformPositions[index];
+ var rot = transformRotations[index];
+ var scl = transformScales[index];
return float4x4.TRS(pos, rot, scl);
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs.meta
index dc6f58bc..206cef25 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupData.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs
new file mode 100644
index 00000000..13e1cc18
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs
@@ -0,0 +1,202 @@
+// Magica Cloth 2.
+// Copyright (c) 2024 MagicaSoft.
+// https://magicasoft.jp
+using System;
+using System.Collections.Generic;
+using Unity.Collections;
+using UnityEngine;
+
+namespace MagicaCloth2
+{
+ public partial class RenderSetupData
+ {
+ ///
+ /// PreBuildの共有部分保存データ
+ ///
+ [System.Serializable]
+ public class ShareSerializationData
+ {
+ public ResultCode result;
+ public string name;
+ public SetupType setupType;
+
+ // Mesh ---------------------------------------------------------------
+ public Mesh originalMesh;
+ public int vertexCount;
+ public bool hasSkinnedMesh;
+ public bool hasBoneWeight;
+ public int skinRootBoneIndex;
+ public int skinBoneCount;
+ // MeshDataでは取得できないメッシュ情報
+ public List bindPoseList;
+ public byte[] bonesPerVertexArray;
+ public byte[] boneWeightArray;
+ public Vector3[] localPositions;
+ public Vector3[] localNormals;
+ public Vector4[] localTangents; // option
+
+ // Bone ---------------------------------------------------------------
+ public BoneConnectionMode boneConnectionMode;
+
+ // Common -------------------------------------------------------------
+ public int renderTransformIndex;
+
+ // --------------------------------------------------------------------
+ public bool HasTangent => localTangents?.Length > 0;
+ }
+
+ public ShareSerializationData ShareSerialize()
+ {
+ var sdata = new ShareSerializationData();
+ try
+ {
+ sdata.result = result;
+ sdata.name = name;
+ sdata.setupType = setupType;
+
+ // Mesh
+ sdata.originalMesh = originalMesh;
+ sdata.vertexCount = vertexCount;
+ sdata.hasSkinnedMesh = hasSkinnedMesh;
+ sdata.hasBoneWeight = hasBoneWeight;
+ sdata.skinRootBoneIndex = skinRootBoneIndex;
+ sdata.skinBoneCount = skinBoneCount;
+ sdata.bindPoseList = new List(bindPoseList);
+ sdata.bonesPerVertexArray = bonesPerVertexArray.MC2ToRawBytes();
+ sdata.boneWeightArray = boneWeightArray.MC2ToRawBytes();
+ sdata.localPositions = originalMesh.vertices;
+ sdata.localNormals = originalMesh.normals;
+ if (originalMesh.HasVertexAttribute(UnityEngine.Rendering.VertexAttribute.Tangent))
+ sdata.localTangents = originalMesh.tangents;
+
+ // Bone
+ sdata.boneConnectionMode = boneConnectionMode;
+
+ // Common
+ sdata.renderTransformIndex = renderTransformIndex;
+ }
+ catch (Exception exception)
+ {
+ Debug.LogException(exception);
+ }
+
+ return sdata;
+ }
+
+ public static RenderSetupData ShareDeserialize(ShareSerializationData sdata)
+ {
+ var setup = new RenderSetupData();
+ setup.isManaged = true;
+
+ try
+ {
+ setup.name = sdata.name;
+ setup.setupType = sdata.setupType;
+
+ // Mesh
+ setup.originalMesh = sdata.originalMesh;
+ setup.vertexCount = sdata.vertexCount;
+ setup.hasSkinnedMesh = sdata.hasSkinnedMesh;
+ setup.hasBoneWeight = sdata.hasBoneWeight;
+ setup.skinRootBoneIndex = sdata.skinRootBoneIndex;
+ setup.skinBoneCount = sdata.skinBoneCount;
+ setup.bindPoseList = new List(sdata.bindPoseList);
+ setup.bonesPerVertexArray = NativeArrayExtensions.MC2FromRawBytes(sdata.bonesPerVertexArray, Allocator.Persistent);
+ setup.boneWeightArray = NativeArrayExtensions.MC2FromRawBytes(sdata.boneWeightArray, Allocator.Persistent);
+
+ // PreBuildではmeshDataArrayを生成しない
+ // その代わりに保存したlocalPositions/Normalsを復元する
+ setup.localPositions = new NativeArray(sdata.localPositions, Allocator.Persistent);
+ setup.localNormals = new NativeArray(sdata.localNormals, Allocator.Persistent);
+ if (sdata.HasTangent)
+ setup.localTangents = new NativeArray(sdata.localTangents, Allocator.Persistent);
+
+ // Bone
+ setup.boneConnectionMode = sdata.boneConnectionMode;
+
+ // Common
+ setup.renderTransformIndex = sdata.renderTransformIndex;
+
+ setup.result.SetSuccess();
+ }
+ catch (Exception exception)
+ {
+ Debug.LogException(exception);
+ setup.result.SetError(Define.Result.PreBuild_InvalidRenderSetupData);
+ }
+
+ return setup;
+ }
+
+ //=========================================================================================
+ ///
+ /// PreBuild固有部分の保存データ
+ ///
+ [System.Serializable]
+ public class UniqueSerializationData : ITransform
+ {
+ public ResultCode result;
+
+ // Mesh ---------------------------------------------------------------
+ public Renderer renderer;
+ public SkinnedMeshRenderer skinRenderer;
+ public MeshFilter meshFilter;
+ public Mesh originalMesh;
+
+ // Common -------------------------------------------------------------
+ public List transformList;
+
+ public void GetUsedTransform(HashSet transformSet)
+ {
+ transformList?.ForEach(x =>
+ {
+ if (x)
+ transformSet.Add(x);
+ });
+ }
+
+ public void ReplaceTransform(Dictionary replaceDict)
+ {
+ if (transformList != null)
+ {
+ for (int i = 0; i < transformList.Count; i++)
+ {
+ var t = transformList[i];
+ if (t)
+ {
+ int id = t.GetInstanceID();
+ if (id != 0 && replaceDict.ContainsKey(id))
+ {
+ transformList[i] = replaceDict[id];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public UniqueSerializationData UniqueSerialize()
+ {
+ var sdata = new UniqueSerializationData();
+ try
+ {
+ sdata.result = result;
+
+ // Mesh
+ sdata.renderer = renderer;
+ sdata.skinRenderer = skinRenderer;
+ sdata.meshFilter = meshFilter;
+ sdata.originalMesh = originalMesh;
+
+ // Common
+ sdata.transformList = new List(transformList);
+ }
+ catch (Exception exception)
+ {
+ Debug.LogException(exception);
+ }
+
+ return sdata;
+ }
+ }
+}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs.meta
new file mode 100644
index 00000000..e8fa4084
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs.meta
@@ -0,0 +1,18 @@
+fileFormatVersion: 2
+guid: 15097613d7348214ca528d3986504ece
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupDataSerialization.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs
new file mode 100644
index 00000000..b725ea11
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs
@@ -0,0 +1,356 @@
+// Magica Cloth 2.
+// Copyright (c) 2025 MagicaSoft.
+// https://magicasoft.jp
+using System;
+using System.Collections.Generic;
+using Unity.Burst;
+using Unity.Collections;
+using Unity.Jobs;
+using Unity.Mathematics;
+using UnityEngine;
+
+namespace MagicaCloth2
+{
+ [System.Serializable]
+ public class RenderSetupSerializeData : ITransform
+ {
+ public RenderSetupData.SetupType setupType;
+
+ public int vertexCount;
+ public bool hasSkinnedMesh;
+ public bool hasBoneWeight;
+ public int skinRootBoneIndex;
+ public int renderTransformIndex;
+ public int skinBoneCount;
+ public int transformCount;
+ public int useTransformCount;
+
+ public int[] useTransformIndexArray;
+
+ public Transform[] transformArray;
+ public float3[] transformPositions;
+ public quaternion[] transformRotations;
+ public float3[] transformLocalPositions;
+ public quaternion[] transformLocalRotations;
+ public float3[] transformScales;
+
+ public float4x4 initRenderLocalToWorld; // 初期化時の基準マトリックス(LtoW)
+ public float4x4 initRenderWorldtoLocal; // 初期化時の基準マトリックス(WtoL)
+ public quaternion initRenderRotation; // 初期化時の基準回転
+ public float3 initRenderScale; // 初期化時の基準スケール
+
+ public Mesh originalMesh; // 変更前のオリジナル共有メッシュ(SkinnedMeshRender利用時のみ)
+
+ public bool DataValidateMeshCloth(Renderer ren)
+ {
+ if (setupType != RenderSetupData.SetupType.MeshCloth)
+ return false;
+ if (ren == null)
+ return false;
+
+ if (useTransformIndexArray == null || useTransformIndexArray.Length == 0)
+ return false;
+
+ if (ren is SkinnedMeshRenderer)
+ {
+ if (hasSkinnedMesh == false)
+ return false;
+
+ var sren = ren as SkinnedMeshRenderer;
+ var smesh = sren.sharedMesh;
+ if (smesh == null)
+ return false;
+
+ // 重いか?
+ //int bcnt = smesh.bindposes?.Length ?? 0;
+ //if (skinBoneCount != bcnt)
+ // return false;
+ }
+ else
+ {
+ if (hasSkinnedMesh)
+ return false;
+
+ var filter = ren.GetComponent();
+ if (filter == null)
+ return false;
+
+ var smesh = filter.sharedMesh;
+ if (smesh == null)
+ return false;
+ }
+
+ if (DataValidateTransform() == false)
+ return false;
+
+ return true;
+ }
+
+ public bool DataValidateBoneCloth(ClothSerializeData sdata, RenderSetupData.SetupType clothType)
+ {
+ if (setupType != clothType)
+ return false;
+ if (hasSkinnedMesh)
+ return false;
+ if (hasBoneWeight)
+ return false;
+
+ if (DataValidateTransform() == false)
+ return false;
+
+ // root bone
+ foreach (var rootBone in sdata.rootBones)
+ {
+ if (rootBone == null || Array.FindIndex(transformArray, x => x == rootBone) < 0)
+ return false;
+ }
+
+ return true;
+ }
+
+ public bool DataValidateTransform()
+ {
+ if (transformCount == 0)
+ return false;
+ if (useTransformCount == 0)
+ return false;
+
+ int ucnt = useTransformCount;
+
+ if (ucnt != (useTransformIndexArray?.Length ?? 0))
+ return false;
+ if (ucnt != (transformArray?.Length ?? 0))
+ return false;
+ if (Array.FindIndex(transformArray, x => x == null) >= 0)
+ return false;
+
+ if (ucnt != (transformPositions?.Length ?? 0))
+ return false;
+ if (ucnt != (transformRotations?.Length ?? 0))
+ return false;
+ if (ucnt != (transformLocalPositions?.Length ?? 0))
+ return false;
+ if (ucnt != (transformLocalRotations?.Length ?? 0))
+ return false;
+ if (ucnt != (transformScales?.Length ?? 0))
+ return false;
+
+ return true;
+ }
+
+ public bool Serialize(RenderSetupData sd)
+ {
+ Debug.Assert(sd != null);
+ Debug.Assert(sd.TransformCount > 0);
+
+ setupType = sd.setupType;
+ vertexCount = sd.vertexCount;
+ hasSkinnedMesh = sd.hasSkinnedMesh;
+ hasBoneWeight = sd.hasBoneWeight;
+ skinRootBoneIndex = sd.skinRootBoneIndex;
+ renderTransformIndex = sd.renderTransformIndex;
+ skinBoneCount = sd.skinBoneCount;
+ transformCount = sd.TransformCount;
+ useTransformCount = 0;
+ originalMesh = null;
+
+ if (sd.TransformCount > 0)
+ {
+ int tcnt = sd.TransformCount;
+
+ using var useTransformIndexList = new NativeList(tcnt, Allocator.TempJob);
+ if (setupType == RenderSetupData.SetupType.MeshCloth)
+ {
+ // MeshClothではウエイトとして利用されているボーンのみパックする
+ if (hasBoneWeight)
+ {
+ var job = new CalcUseBoneArrayJob2()
+ {
+ boneCount = skinBoneCount,
+ boneWeightArray = sd.boneWeightArray,
+ useBoneIndexList = useTransformIndexList,
+ };
+ job.Run();
+ if (skinRootBoneIndex >= skinBoneCount)
+ useTransformIndexList.Add(skinRootBoneIndex);
+ useTransformIndexList.Add(renderTransformIndex);
+ }
+ else
+ {
+ // 通常メッシュはそのまま
+ for (int i = 0; i < tcnt; i++)
+ useTransformIndexList.Add(i);
+ }
+
+ // オリジナルメッシュを記録
+ if (sd.originalMesh && sd.originalMesh.name.Contains("(Clone)") == false)
+ {
+ originalMesh = sd.originalMesh;
+ }
+ }
+ else
+ {
+ // BoneCloth系はそのまま
+ for (int i = 0; i < tcnt; i++)
+ useTransformIndexList.Add(i);
+ }
+
+ using var tempArray = useTransformIndexList.ToArray(Allocator.TempJob);
+ useTransformIndexArray = tempArray.ToArray();
+
+ int ucnt = useTransformIndexArray.Length;
+
+ useTransformCount = ucnt;
+
+ transformArray = new Transform[ucnt];
+ transformPositions = new float3[ucnt];
+ transformRotations = new quaternion[ucnt];
+ transformLocalPositions = new float3[ucnt];
+ transformLocalRotations = new quaternion[ucnt];
+ transformScales = new float3[ucnt];
+
+ for (int i = 0; i < ucnt; i++)
+ {
+ int tindex = useTransformIndexArray[i];
+
+ transformArray[i] = sd.transformList[tindex];
+ transformPositions[i] = sd.transformPositions[tindex];
+ transformRotations[i] = sd.transformRotations[tindex];
+ transformLocalPositions[i] = sd.transformLocalPositions[tindex];
+ transformLocalRotations[i] = sd.transformLocalRotations[tindex];
+ transformScales[i] = sd.transformScales[tindex];
+ }
+ }
+
+ initRenderLocalToWorld = sd.initRenderLocalToWorld;
+ initRenderWorldtoLocal = sd.initRenderWorldtoLocal;
+ initRenderRotation = sd.initRenderRotation;
+ initRenderScale = sd.initRenderScale;
+
+ return true;
+ }
+
+ [BurstCompile]
+ struct CalcUseBoneArrayJob2 : IJob
+ {
+ public int boneCount;
+
+ [Unity.Collections.ReadOnly]
+ public NativeArray boneWeightArray;
+ public NativeList useBoneIndexList;
+
+ public void Execute()
+ {
+ var useBoneArray = new NativeArray(boneCount, Allocator.Temp);
+ int cnt = boneWeightArray.Length;
+ int packCnt = 0;
+ for (int i = 0; i < cnt; i++)
+ {
+ var bw1 = boneWeightArray[i];
+ if (bw1.weight > 0.0f)
+ {
+ byte oldFlag = useBoneArray[bw1.boneIndex];
+ if (oldFlag == 0)
+ packCnt++;
+ useBoneArray[bw1.boneIndex] = 1;
+ }
+ }
+
+ // 利用Boneのインデックスをパックする
+ for (int i = 0; i < boneCount; i++)
+ {
+ byte flag = useBoneArray[i];
+ if (flag != 0)
+ {
+ useBoneIndexList.Add(i);
+ }
+ }
+ useBoneArray.Dispose();
+ }
+ }
+
+ public int GetLocalHash()
+ {
+ int hash = 0;
+
+ hash += (int)setupType * 100;
+ hash += vertexCount;
+ hash += hasSkinnedMesh ? 1 : 0;
+ hash += hasBoneWeight ? 1 : 0;
+ hash += skinRootBoneIndex;
+ hash += renderTransformIndex;
+ hash += skinBoneCount;
+ hash += transformCount;
+ hash += useTransformCount;
+
+ hash += useTransformIndexArray?.Length ?? 0;
+ hash += transformArray?.Length ?? 0;
+ hash += transformPositions?.Length ?? 0;
+ hash += transformRotations?.Length ?? 0;
+ hash += transformLocalPositions?.Length ?? 0;
+ hash += transformLocalRotations?.Length ?? 0;
+ hash += transformScales?.Length ?? 0;
+
+ if (transformArray != null)
+ foreach (var t in transformArray)
+ hash += t != null ? (456 + t.childCount * 789) : 0;
+
+ if (originalMesh != null)
+ hash += originalMesh.vertexCount;
+
+ return hash;
+ }
+
+ public int GetGlobalHash()
+ {
+ int hash = 0;
+
+ if (transformArray != null)
+ {
+ foreach (var t in transformArray)
+ {
+ if (t)
+ {
+ hash += t.localPosition.GetHashCode();
+ hash += t.localRotation.GetHashCode();
+ hash += t.localScale.GetHashCode();
+ }
+ }
+ }
+
+ // レンダーワールドスケールのみ監視する
+ // ワールドスケールはちょっとした移動や回転などで浮動小数点誤差が出るので少数3桁まででハッシュ化する
+ int3 intScale = (int3)math.round(initRenderScale * 1000);
+ //Debug.Log($"★initScale:{intScale}");
+ hash += intScale.GetHashCode();
+
+ return hash;
+ }
+
+ public void GetUsedTransform(HashSet transformSet)
+ {
+ if (transformArray != null)
+ {
+ foreach (var t in transformArray)
+ {
+ if (t)
+ transformSet.Add(t);
+ }
+ }
+ }
+
+ public void ReplaceTransform(Dictionary replaceDict)
+ {
+ if (transformArray == null)
+ return;
+ for (int i = 0; i < transformArray.Length; i++)
+ {
+ var t = transformArray[i];
+ if (t && replaceDict.ContainsKey(t.GetInstanceID()))
+ {
+ transformArray[i] = replaceDict[t.GetInstanceID()];
+ }
+ }
+ }
+ }
+}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs.meta
new file mode 100644
index 00000000..162302cb
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs.meta
@@ -0,0 +1,18 @@
+fileFormatVersion: 2
+guid: 98f83594b09a8c5469b78d1d22047ecd
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/Render/RenderSetupSerializeData.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs
index e1cbd84e..be2dc640 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs
@@ -2,10 +2,9 @@
// Copyright (c) 2023 MagicaSoft.
// https://magicasoft.jp
using System.Collections.Generic;
+using System.Linq;
using System.Text;
-using Unity.Burst;
using Unity.Collections;
-using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
@@ -42,14 +41,31 @@ namespace MagicaCloth2
}
///
- /// フラグ(8bit)
- /// 下位4bitはコライダー種類
- /// 上位4bitはフラグ
+ /// シンメトリータイプ(最大15まで)
///
- public const byte Flag_Valid = 0x10; // データの有無
- public const byte Flag_Enable = 0x20; // 有効状態
- public const byte Flag_Reset = 0x40; // 位置リセット
- public ExNativeArray flagArray;
+ public enum SymmetryType : byte
+ {
+ None = 0,
+ X_Symmetry = 1,
+ Y_Symmetry = 2,
+ Z_Symmetry = 3,
+ XYZ_Symmetry = 4,
+ }
+
+ ///
+ /// フラグ(16bit)
+ /// (0~3:4bit)コライダー種類
+ /// (4~7:4bit)シンメトリータイプ
+ /// (8~15:8bit)フラグ
+ ///
+ public const ushort Flag_Valid = 0x0100; // データの有無
+ public const ushort Flag_Enable = 0x0200; // 有効状態
+ public const ushort Flag_Reset = 0x0400; // 位置リセット
+ public const ushort Flag_Reverse = 0x0800; // 方向逆転
+ public const ushort Flag_Symmetry = 0x1000; // シンメトリー
+ public const ushort Flag_SymmetryReverse = 0x2000; // シンメトリーによる方向フリップ
+ public const ushort Flag_ScaleSuspend = 0x4000; // 極小スケールによる機能停止
+ public ExNativeArray flagArray;
///
/// トランスフォームからの中心ローカルオフセット位置
@@ -66,7 +82,7 @@ namespace MagicaCloth2
///
/// 現フレーム姿勢
- /// トランスフォームからスナップされたチームローカル姿勢
+ /// トランスフォームからスナップされた姿勢(ワールド)
/// センターオフセットも計算される
///
public ExNativeArray framePositions;
@@ -74,36 +90,33 @@ namespace MagicaCloth2
public ExNativeArray frameScales;
///
- /// 1つ前のフレーム姿勢
+ /// 1つ前のフレーム姿勢(ワールド)
///
public ExNativeArray oldFramePositions;
public ExNativeArray oldFrameRotations;
- //public ExNativeArray oldFrameScales;
///
- /// 現ステップでの姿勢
+ /// 現ステップでの姿勢(ワールド)
///
public ExNativeArray nowPositions;
public ExNativeArray nowRotations;
- //public ExNativeArray nowScales;
+ ///
+ /// 前ステップでの姿勢(ワールド)
+ ///
public ExNativeArray oldPositions;
public ExNativeArray oldRotations;
///
- /// 有効なコライダーデータ数
+ /// シンメトリー用のメインコライダーへのローカルインデックス配列
///
- public int DataCount => teamIdArray?.Count ?? 0;
+ public ExNativeArray mainColliderIndices;
///
/// 登録コライダーコンポーネント
+ /// 現在はデバッグ用
///
- public HashSet colliderSet = new HashSet();
-
- ///
- /// 登録コライダー数
- ///
- public int ColliderCount => colliderSet.Count;
+ HashSet colliderSet = new HashSet();
bool isValid = false;
@@ -137,13 +150,12 @@ namespace MagicaCloth2
frameScales?.Dispose();
nowPositions?.Dispose();
nowRotations?.Dispose();
- //nowScales?.Dispose();
oldFramePositions?.Dispose();
oldFrameRotations?.Dispose();
- //oldFrameScales?.Dispose();
oldPositions?.Dispose();
oldRotations?.Dispose();
workDataArray?.Dispose();
+ mainColliderIndices?.Dispose();
teamIdArray = null;
flagArray = null;
@@ -153,13 +165,12 @@ namespace MagicaCloth2
frameScales = null;
nowPositions = null;
nowRotations = null;
- //nowScales = null;
oldFramePositions = null;
oldFrameRotations = null;
- //oldFrameScales = null;
oldPositions = null;
oldRotations = null;
workDataArray = null;
+ mainColliderIndices = null;
colliderSet.Clear();
}
@@ -175,7 +186,7 @@ namespace MagicaCloth2
const int capacity = 256;
teamIdArray = new ExNativeArray(capacity);
- flagArray = new ExNativeArray(capacity);
+ flagArray = new ExNativeArray(capacity);
centerArray = new ExNativeArray(capacity);
sizeArray = new ExNativeArray(capacity);
framePositions = new ExNativeArray(capacity);
@@ -183,13 +194,12 @@ namespace MagicaCloth2
frameScales = new ExNativeArray(capacity);
nowPositions = new ExNativeArray(capacity);
nowRotations = new ExNativeArray(capacity);
- //nowScales = new ExNativeArray(capacity);
oldFramePositions = new ExNativeArray(capacity);
oldFrameRotations = new ExNativeArray(capacity);
- //oldFrameScales = new ExNativeArray(capacity);
oldPositions = new ExNativeArray(capacity);
oldRotations = new ExNativeArray(capacity);
workDataArray = new ExNativeArray(capacity);
+ mainColliderIndices = new ExNativeArray(capacity);
isValid = true;
}
@@ -214,32 +224,45 @@ namespace MagicaCloth2
int cnt = cprocess.cloth.SerializeData.colliderCollisionConstraint.ColliderLength;
if (cnt > 0)
{
+ // シンメトリーも考慮した初期コライダーの数を算出する
+ var clist = cprocess.cloth.SerializeData.colliderCollisionConstraint.colliderList;
+ int activeCount = 0;
+ clist.ForEach(x =>
+ {
+ if (x)
+ activeCount += x.symmetryMode != ColliderSymmetryMode.None ? 2 : 1;
+ });
+ //Debug.Log($"[{cprocess.cloth.name}] ActiveColliderCount:{activeCount}");
+
+ // 初期コライダーの領域確保
int teamId = cprocess.TeamId;
ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId);
-
- // コライダー数で初期化
- tdata.colliderChunk = teamIdArray.AddRange(cnt, (short)teamId);
- flagArray.AddRange(cnt, default);
- centerArray.AddRange(cnt);
- sizeArray.AddRange(cnt);
- framePositions.AddRange(cnt);
- frameRotations.AddRange(cnt);
- frameScales.AddRange(cnt);
- nowPositions.AddRange(cnt);
- nowRotations.AddRange(cnt);
- //nowScales.AddRange(cnt);
- oldFramePositions.AddRange(cnt);
- oldFrameRotations.AddRange(cnt);
- //oldFrameScales.AddRange(cnt);
- oldPositions.AddRange(cnt);
- oldRotations.AddRange(cnt);
- workDataArray.AddRange(cnt);
- tdata.colliderTransformChunk = MagicaManager.Bone.AddTransform(cnt, teamId); // 領域のみ
+ tdata.colliderChunk = teamIdArray.AddRange(activeCount, (short)teamId);
+ flagArray.AddRange(activeCount, default);
+ centerArray.AddRange(activeCount);
+ sizeArray.AddRange(activeCount);
+ framePositions.AddRange(activeCount);
+ frameRotations.AddRange(activeCount);
+ frameScales.AddRange(activeCount);
+ nowPositions.AddRange(activeCount);
+ nowRotations.AddRange(activeCount);
+ oldFramePositions.AddRange(activeCount);
+ oldFrameRotations.AddRange(activeCount);
+ oldPositions.AddRange(activeCount);
+ oldRotations.AddRange(activeCount);
+ workDataArray.AddRange(activeCount);
+ mainColliderIndices.AddRange(activeCount);
+ Transform t = cprocess.cloth.ClothTransform;
+ tdata.colliderTransformChunk = MagicaManager.Bone.AddTransform(activeCount, teamId, t); // 領域のみ
tdata.colliderCount = 0;
- cprocess.colliderList.AddRange(new ColliderComponent[cnt]); // nullで領域確保
// 初期コライダー登録
- InitColliders(cprocess);
+ for (int i = 0; i < clist.Count; i++)
+ {
+ var col = clist[i];
+ if (col && cprocess.colliderDict.ContainsKey(col) == false)
+ AddCollider(cprocess, col);
+ }
}
}
@@ -255,15 +278,18 @@ namespace MagicaCloth2
int teamId = cprocess.TeamId;
// コライダー解除
- foreach (var col in cprocess.colliderList)
+ foreach (var col in cprocess.colliderDict.Keys)
{
if (col)
{
- col.Exit(teamId);
- colliderSet.Remove(col);
+ if (col.Exit(teamId))
+ {
+ // 利用者0
+ colliderSet.Remove(col);
+ }
}
}
- cprocess.colliderList.Clear();
+ cprocess.colliderDict.Clear();
ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId);
@@ -277,13 +303,12 @@ namespace MagicaCloth2
frameScales.Remove(c);
nowPositions.Remove(c);
nowRotations.Remove(c);
- //nowScales.Remove(c);
oldFramePositions.Remove(c);
oldFrameRotations.Remove(c);
- //oldFrameScales.Remove(c);
oldPositions.Remove(c);
oldRotations.Remove(c);
workDataArray.Remove(c);
+ mainColliderIndices.Remove(c);
tdata.colliderChunk.Clear();
tdata.colliderCount = 0;
@@ -295,60 +320,36 @@ namespace MagicaCloth2
//=========================================================================================
///
- /// 初期コライダーの登録
- ///
- ///
- internal void InitColliders(ClothProcess cprocess)
- {
- var clist = cprocess.cloth.SerializeData.colliderCollisionConstraint.colliderList;
- if (clist.Count == 0)
- return;
-
- ref var tdata = ref MagicaManager.Team.GetTeamDataRef(cprocess.TeamId);
- int index = 0;
- for (int i = 0; i < clist.Count; i++)
- {
- var col = clist[i];
- if (col && cprocess.colliderList.Contains(col) == false)
- {
- AddColliderInternal(cprocess, col, index, tdata.colliderChunk.startIndex + index, tdata.colliderTransformChunk.startIndex + index);
- tdata.colliderCount++;
- index++;
- }
- }
- }
-
- ///
- /// コライダーの内容を更新する
+ /// コライダーのリスト内容を更新する
+ /// これはMagicaClothコンポーネント側のコライダーリストが変更された場合
+ /// つまりパラメータの変更ではない
///
///
internal void UpdateColliders(ClothProcess cprocess)
{
if (isValid == false)
return;
+
+ // ここではコライダーリストへのコンポーネント追加削除だけで、シンメトリーなどの切り替えは考慮しなくていい
var clist = cprocess.cloth.SerializeData.colliderCollisionConstraint.colliderList;
- // 現在の登録コライダーと比較し削除と追加を行う
- // 既存削除
- for (int i = 0, cnt = cprocess.ColliderCapacity; i < cnt;)
+ // 現在の登録コライダーと比較し不要なコライダーを削除する
+ var keys = cprocess.colliderDict.Keys.ToList();
+ foreach (ColliderComponent col in keys)
{
- var col = cprocess.colliderList[i];
if (col && clist.Contains(col) == false)
{
- // コライダー消滅
+ // コライダー削除
RemoveCollider(col, cprocess.TeamId);
}
- else
- i++;
}
- // 新規追加
+ // 現在の登録コライダーと比較し必要なコライダーを追加する
foreach (var col in clist)
{
- if (col && cprocess.GetColliderIndex(col) < 0)
+ if (col && cprocess.colliderDict.ContainsKey(col) == false)
{
AddCollider(cprocess, col);
- //Debug.Log($"コライダー追加:{col.name}");
}
}
}
@@ -364,12 +365,38 @@ namespace MagicaCloth2
return;
if (col == null)
return;
- if (cprocess.GetColliderIndex(col) >= 0)
+ if (cprocess.colliderDict.ContainsKey(col))
return; // すでに追加済み
ref var tdata = ref MagicaManager.Team.GetTeamDataRef(cprocess.TeamId);
Debug.Assert(tdata.IsValid);
+ // Main
+ AddColliderInternal(ref tdata, cprocess, col, false);
+ colliderSet.Add(col);
+
+ // Symmetry
+ col.SetActiveSymmetryMode(firstOnly: true); // シンメトリー情報更新
+ AddColliderInternal(ref tdata, cprocess, col, true);
+
+ // コライダーコンポーネント側にも登録する(紐づけ)
+ col.Register(cprocess.TeamId);
+ }
+
+ void AddColliderInternal(ref TeamManager.TeamData tdata, ClothProcess cprocess, ColliderComponent col, bool isSymmetry)
+ {
+ // シンメトリーの有効性
+ if (isSymmetry)
+ {
+ if (col.ActiveSymmetryMode == ColliderSymmetryMode.None)
+ return;
+ if (col.ActiveSymmetryTarget == null)
+ return;
+ }
+
+ int teamId = cprocess.TeamId;
+
+ // 領域拡張
if (tdata.colliderChunk.IsValid == false)
{
// 新規確保
@@ -388,11 +415,12 @@ namespace MagicaCloth2
oldPositions.AddRange(newCount);
oldRotations.AddRange(newCount);
workDataArray.AddRange(newCount);
- tdata.colliderTransformChunk = MagicaManager.Bone.AddTransform(newCount, cprocess.TeamId); // 領域のみ
+ mainColliderIndices.AddRange(newCount);
+ Transform t = cprocess.cloth.ClothTransform;
+ tdata.colliderTransformChunk = MagicaManager.Bone.AddTransform(newCount, cprocess.TeamId, t); // 領域のみ
tdata.colliderCount = 0;
- cprocess.colliderList.AddRange(new ColliderComponent[newCount]); // nullで領域確保
}
- else if (tdata.ColliderCount == tdata.colliderChunk.dataLength)
+ else if (tdata.UseColliderCount == tdata.colliderChunk.dataLength)
{
// コライダー配列のキャパシティ上限なら拡張する
// 拡張
@@ -412,28 +440,140 @@ namespace MagicaCloth2
oldPositions.Expand(oldColliderChunk, newCount);
oldRotations.Expand(oldColliderChunk, newCount);
workDataArray.Expand(oldColliderChunk, newCount);
+ mainColliderIndices.Expand(oldColliderChunk, newCount);
// コライダートランスフォーム拡張
var oldColliderTransformChunk = tdata.colliderTransformChunk;
tdata.colliderTransformChunk = MagicaManager.Bone.Expand(oldColliderTransformChunk, newCount);
-
- // コライダー配列拡張
- cprocess.colliderList.AddRange(new ColliderComponent[Define.System.ExpandedColliderCount]);
}
- // 最後に追加する
- int index = tdata.colliderCount;
- int arrayIndex = tdata.colliderChunk.startIndex + index;
- int transformIndex = tdata.colliderTransformChunk.startIndex + index;
- AddColliderInternal(cprocess, col, index, arrayIndex, transformIndex);
+ // 追加インデックス
+ int localIndex = tdata.UseColliderCount;
+ int arrayIndex = tdata.colliderChunk.startIndex + localIndex;
+ int transformIndex = tdata.colliderTransformChunk.startIndex + localIndex;
+
+ // フラグ
+ var flag = new ExBitFlag16();
+ flag = DataUtility.SetColliderType(flag, col.GetColliderType());
+ flag.SetFlag(Flag_Valid, true);
+ flag.SetFlag(Flag_Enable, col.isActiveAndEnabled);
+ flag.SetFlag(Flag_Reset, true);
+ flag.SetFlag(Flag_Reverse, col.IsReverseDirection());
+ // ワールド姿勢
+ var ct = col.transform;
+ float3 pos = float3.zero;
+ quaternion rot = quaternion.identity;
+ float3 scl = 1;
+ float3 center = col.center;
+ // 登録トランスフォーム
+ Transform target = ct;
+ if (isSymmetry)
+ {
+ // シンメトリー
+ // ここでは姿勢計算は不要。方向性のみでよい。
+ SymmetryType symType;
+ switch (col.ActiveSymmetryMode)
+ {
+ case ColliderSymmetryMode.X_Symmetry:
+ symType = SymmetryType.X_Symmetry;
+ break;
+ case ColliderSymmetryMode.Y_Symmetry:
+ symType = SymmetryType.Y_Symmetry;
+ break;
+ case ColliderSymmetryMode.Z_Symmetry:
+ symType = SymmetryType.Z_Symmetry;
+ break;
+ case ColliderSymmetryMode.XYZ_Symmetry:
+ symType = SymmetryType.XYZ_Symmetry;
+ break;
+ default:
+ Develop.LogError("Unknown active symmetry mode.");
+ return;
+ }
+ flag = DataUtility.SetSymmetryType(flag, symType);
+
+ // 方向性
+ float direction = 1.0f;
+ if (col is MagicaCapsuleCollider)
+ {
+ var ccol = col as MagicaCapsuleCollider;
+ if (col.ActiveSymmetryMode == ColliderSymmetryMode.X_Symmetry && ccol.direction == MagicaCapsuleCollider.Direction.X)
+ direction = -1.0f;
+ else if (col.ActiveSymmetryMode == ColliderSymmetryMode.Y_Symmetry && ccol.direction == MagicaCapsuleCollider.Direction.Y)
+ direction = -1.0f;
+ else if (col.ActiveSymmetryMode == ColliderSymmetryMode.Z_Symmetry && ccol.direction == MagicaCapsuleCollider.Direction.Z)
+ direction = -1.0f;
+ else if (col.ActiveSymmetryMode == ColliderSymmetryMode.XYZ_Symmetry)
+ direction = -1.0f;
+ }
+ else if (col is MagicaPlaneCollider)
+ {
+ switch (col.ActiveSymmetryMode)
+ {
+ case ColliderSymmetryMode.Y_Symmetry:
+ case ColliderSymmetryMode.XYZ_Symmetry:
+ direction = -1.0f;
+ break;
+ }
+ }
+
+ // フラグ
+ flag.SetFlag(Flag_Symmetry, true);
+ flag.SetFlag(Flag_SymmetryReverse, direction < 0.0f);
+
+ // 登録トランスフォーム
+ target = col.ActiveSymmetryTarget;
+ }
+
+ // マネージャへ登録
+ teamIdArray[arrayIndex] = (short)teamId;
+ flagArray[arrayIndex] = flag;
+ centerArray[arrayIndex] = center;
+ sizeArray[arrayIndex] = math.max(col.GetSize(), 0.0001f); // 念のため
+ framePositions[arrayIndex] = pos;
+ frameRotations[arrayIndex] = rot;
+ frameScales[arrayIndex] = scl;
+ nowPositions[arrayIndex] = pos;
+ nowRotations[arrayIndex] = rot;
+ oldFramePositions[arrayIndex] = pos;
+ oldFrameRotations[arrayIndex] = rot;
+ oldPositions[arrayIndex] = pos;
+ oldRotations[arrayIndex] = rot;
+ mainColliderIndices[arrayIndex] = 0;
+
+ // ClothProcessにコライダーコンポーネントを登録
+ if (cprocess.colliderDict.ContainsKey(col))
+ {
+ int2 data = cprocess.colliderDict[col];
+ if (isSymmetry)
+ {
+ data.y = localIndex;
+ // メインコライダーローカルインデックスを記録
+ mainColliderIndices[arrayIndex] = data.x;
+ }
+ else
+ data.x = localIndex;
+ cprocess.colliderDict[col] = data;
+ }
+ else
+ {
+ Debug.Assert(isSymmetry == false);
+ cprocess.colliderDict.Add(col, new int2(localIndex, 0));
+ }
+
+ // トランスフォーム登録
+ bool t_enable = cprocess.IsEnable && flag.IsSet(Flag_Enable);
+ var tflag = new ExBitFlag8(TransformManager.Flag_Read);
+ tflag.SetFlag(TransformManager.Flag_Enable, t_enable);
+ MagicaManager.Bone.SetTransform(target, tflag, transformIndex, teamId);
tdata.colliderCount++;
}
+
///
/// コライダーを削除する
- /// ここでは領域は削除せずにデータのみを無効化させる
- /// 領域は生存する最後尾のデータと入れ替えられる(SwapBack)
+ /// 削除領域は生存する最後尾のデータと入れ替えられる(SwapBack)
///
///
///
@@ -441,6 +581,29 @@ namespace MagicaCloth2
{
if (isValid == false)
return;
+ if (col == null || teamId == 0)
+ return;
+
+ // Symmetry
+ RemoveColliderInternal(col, teamId, true);
+
+ // Main
+ RemoveColliderInternal(col, teamId, false);
+
+ // コライダーコンポーネント側からも削除登録する(紐づけ解除)
+ if (col.Exit(teamId))
+ {
+ // 利用者0
+ colliderSet.Remove(col);
+ }
+ }
+
+ void RemoveColliderInternal(ColliderComponent col, int teamId, bool isSymmetry)
+ {
+ if (isValid == false)
+ return;
+ if (col == null || teamId == 0)
+ return;
ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId);
int ccnt = tdata.colliderCount;
if (ccnt == 0)
@@ -448,16 +611,23 @@ namespace MagicaCloth2
var cprocess = MagicaManager.Team.GetClothProcess(teamId);
if (cprocess == null)
return;
- int index = cprocess.GetColliderIndex(col);
- if (index < 0)
+ if (cprocess.colliderDict.ContainsKey(col) == false)
return;
+ int2 data = cprocess.colliderDict[col];
+ int localIndex = data.x;
+ if (isSymmetry)
+ {
+ if (data.y == 0)
+ return; // シンメトリーコライダーなし
+ localIndex = data.y;
+ }
- int arrayIndex = tdata.colliderChunk.startIndex + index;
- int transformIndex = tdata.colliderTransformChunk.startIndex + index;
+ int arrayIndex = tdata.colliderChunk.startIndex + localIndex;
+ int transformIndex = tdata.colliderTransformChunk.startIndex + localIndex;
- int swapIndex = ccnt - 1;
- int swapArrayIndex = tdata.colliderChunk.startIndex + swapIndex;
- int swapTransformIndex = tdata.colliderTransformChunk.startIndex + swapIndex;
+ int swapLocalIndex = ccnt - 1;
+ int swapArrayIndex = tdata.colliderChunk.startIndex + swapLocalIndex;
+ int swapTransformIndex = tdata.colliderTransformChunk.startIndex + swapLocalIndex;
if (arrayIndex < swapArrayIndex)
{
@@ -471,12 +641,11 @@ namespace MagicaCloth2
frameScales[arrayIndex] = frameScales[swapArrayIndex];
nowPositions[arrayIndex] = nowPositions[swapArrayIndex];
nowRotations[arrayIndex] = nowRotations[swapArrayIndex];
- //nowScales[arrayIndex] = nowScales[swapArrayIndex];
oldFramePositions[arrayIndex] = oldFramePositions[swapArrayIndex];
oldFrameRotations[arrayIndex] = oldFrameRotations[swapArrayIndex];
- //oldFrameScales[arrayIndex] = oldFrameScales[swapArrayIndex];
oldPositions[arrayIndex] = oldPositions[swapArrayIndex];
oldRotations[arrayIndex] = oldRotations[swapArrayIndex];
+ mainColliderIndices[arrayIndex] = mainColliderIndices[swapArrayIndex];
flagArray[swapArrayIndex] = default;
teamIdArray[swapArrayIndex] = 0;
@@ -486,8 +655,24 @@ namespace MagicaCloth2
MagicaManager.Bone.SetTransform(null, default, swapTransformIndex, 0);
// cprocess
- cprocess.colliderList[index] = cprocess.colliderList[swapIndex];
- cprocess.colliderList[swapIndex] = null;
+ var ckeys = cprocess.colliderDict.Keys.ToList();
+ foreach (ColliderComponent kcol in ckeys)
+ {
+ Debug.Assert(cprocess.colliderDict.ContainsKey(kcol));
+ int2 data2 = cprocess.colliderDict[kcol];
+ if (data2.x == swapLocalIndex)
+ {
+ data2.x = localIndex;
+ cprocess.colliderDict[kcol] = data2;
+ break;
+ }
+ if (data2.y == swapLocalIndex)
+ {
+ data2.y = localIndex;
+ cprocess.colliderDict[kcol] = data2;
+ break;
+ }
+ }
}
else
{
@@ -497,58 +682,16 @@ namespace MagicaCloth2
// transform
MagicaManager.Bone.SetTransform(null, default, transformIndex, 0);
-
- // cprocess
- cprocess.colliderList[index] = null;
}
+ if (isSymmetry)
+ data.y = 0;
+ else
+ data.x = 0;
+ cprocess.colliderDict[col] = data;
+ if (data.x == 0 && data.y == 0 && isSymmetry == false)
+ cprocess.colliderDict.Remove(col); // コライダー削除
tdata.colliderCount--;
-
- colliderSet.Remove(col);
- }
-
- void AddColliderInternal(ClothProcess cprocess, ColliderComponent col, int index, int arrayIndex, int transformIndex)
- {
- int teamId = cprocess.TeamId;
-
- // マネージャへ登録
- teamIdArray[arrayIndex] = (short)teamId;
- var flag = new ExBitFlag8();
- flag = DataUtility.SetColliderType(flag, col.GetColliderType());
- flag.SetFlag(Flag_Valid, true);
- flag.SetFlag(Flag_Enable, col.isActiveAndEnabled);
- flag.SetFlag(Flag_Reset, true);
- flagArray[arrayIndex] = flag;
- centerArray[arrayIndex] = col.center;
- sizeArray[arrayIndex] = col.GetSize();
- var pos = col.transform.position;
- var rot = col.transform.rotation;
- var scl = col.transform.localScale;
- framePositions[arrayIndex] = pos;
- frameRotations[arrayIndex] = rot;
- frameScales[arrayIndex] = scl;
- nowPositions[arrayIndex] = pos;
- nowRotations[arrayIndex] = rot;
- //nowScales[arrayIndex] = scl;
- oldFramePositions[arrayIndex] = pos;
- oldFrameRotations[arrayIndex] = rot;
- //oldFrameScales[arrayIndex] = scl;
- oldPositions[arrayIndex] = pos;
- oldRotations[arrayIndex] = rot;
-
- // チームにコライダーコンポーネントを登録
- cprocess.colliderList[index] = col;
-
- // コライダーコンポーネント側にも登録する
- col.Register(teamId);
-
- // トランスフォーム登録
- bool t_enable = cprocess.IsEnable && flag.IsSet(Flag_Enable);
- var tflag = new ExBitFlag8(TransformManager.Flag_Read);
- tflag.SetFlag(TransformManager.Flag_Enable, t_enable);
- MagicaManager.Bone.SetTransform(col.transform, tflag, transformIndex, teamId);
-
- colliderSet.Add(col);
}
///
@@ -565,19 +708,29 @@ namespace MagicaCloth2
if (tdata.IsValid == false)
return;
var cprocess = MagicaManager.Team.GetClothProcess(teamId);
- int index = cprocess.GetColliderIndex(col);
- if (index < 0)
- return;
- int arrayIndex = tdata.colliderChunk.startIndex + index;
- var flag = flagArray[arrayIndex];
- flag.SetFlag(Flag_Enable, sw);
- flag.SetFlag(Flag_Reset, true); // Enable/Disableどちらでもリセット
- flagArray[arrayIndex] = flag;
- // トランスフォーム有効状態
- int transformIndex = tdata.colliderTransformChunk.startIndex + index;
- bool t_enable = cprocess.IsEnable && flag.IsSet(Flag_Enable);
- MagicaManager.Bone.EnableTransform(transformIndex, t_enable);
+ if (cprocess.colliderDict.ContainsKey(col) == false)
+ return;
+
+ // メイン、シンメトリーの2つをチェック
+ int2 data = cprocess.colliderDict[col];
+ for (int i = 0; i < 2; i++)
+ {
+ int localIndex = data[i];
+ if (i == 1 && localIndex == 0)
+ continue; // シンメトリーのindex0はデータなし
+
+ int arrayIndex = tdata.colliderChunk.startIndex + localIndex;
+ var flag = flagArray[arrayIndex];
+ flag.SetFlag(Flag_Enable, sw);
+ flag.SetFlag(Flag_Reset, true); // Enable/Disableどちらでもリセット
+ flagArray[arrayIndex] = flag;
+
+ // トランスフォーム有効状態
+ int transformIndex = tdata.colliderTransformChunk.startIndex + localIndex;
+ bool t_enable = cprocess.IsEnable && flag.IsSet(Flag_Enable);
+ MagicaManager.Bone.EnableTransform(transformIndex, t_enable);
+ }
}
///
@@ -585,14 +738,14 @@ namespace MagicaCloth2
///
///
///
- internal void EnableTeamCollider(int teamId, bool sw)
+ internal void EnableTeamCollider(int teamId)
{
if (IsValid() == false)
return;
ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId);
if (tdata.IsValid == false)
return;
- if (tdata.ColliderCount == 0)
+ if (tdata.UseColliderCount == 0)
return;
bool teamEnable = tdata.IsEnable;
@@ -604,7 +757,7 @@ namespace MagicaCloth2
// フラグ
var flag = flagArray[arrayIndex];
- flag.SetFlag(Flag_Enable, sw);
+ //flag.SetFlag(Flag_Enable, sw); // コライダーのEnableフラグはコライダー固有のものなので変更する必要はない
flag.SetFlag(Flag_Reset, true); // Enable/Disableどちらでもリセット
flagArray[arrayIndex] = flag;
@@ -616,10 +769,11 @@ namespace MagicaCloth2
///
/// コライダーコンポーネントのパラメータ変更を反映する
+ /// シンメトリーの変更なども反映させる
///
///
///
- internal void UpdateParameters(ColliderComponent col, int teamId)
+ internal void UpdateParameters(ColliderComponent col, int teamId, bool changeSymmetry)
{
if (IsValid() == false)
return;
@@ -628,119 +782,193 @@ namespace MagicaCloth2
if (tdata.IsValid == false)
return;
var cprocess = MagicaManager.Team.GetClothProcess(teamId);
- int index = cprocess.GetColliderIndex(col);
- if (index < 0)
+ if (cprocess.colliderDict.ContainsKey(col) == false)
return;
- int arrayIndex = tdata.colliderChunk.startIndex + index;
+ int2 data = cprocess.colliderDict[col];
+ // Main
+ // メインコライダーは変更のみ考える
+ // メインは削除されることはない。Transformの変更もない。
+ int localIndex = data.x;
+ int arrayIndex = tdata.colliderChunk.startIndex + localIndex;
var flag = flagArray[arrayIndex];
flag = DataUtility.SetColliderType(flag, col.GetColliderType());
+ flag.SetFlag(Flag_Reverse, col.IsReverseDirection());
flagArray[arrayIndex] = flag;
centerArray[arrayIndex] = col.center;
sizeArray[arrayIndex] = math.max(col.GetSize(), 0.0001f); // 念のため
+
+ // Symmetry
+ if (col.ActiveSymmetryMode != ColliderSymmetryMode.None && col.ActiveSymmetryTarget != null)
+ {
+ // シンメトリーあり
+ if (changeSymmetry)
+ {
+ // シンメトリーのモードまたはターゲットの変更
+ // 一旦削除して再度追加する
+ RemoveColliderInternal(col, teamId, true);
+ AddColliderInternal(ref tdata, cprocess, col, true);
+ //Debug.Log($"remove and add symmetry.");
+ }
+ else if (data.y > 0)
+ {
+ // シンメトリーのモードおよびターゲットは変更されていない
+ // パラメータの変更のみ
+ localIndex = data.y;
+ arrayIndex = tdata.colliderChunk.startIndex + localIndex;
+ flag = flagArray[arrayIndex];
+ flag = DataUtility.SetColliderType(flag, col.GetColliderType());
+ flag.SetFlag(Flag_Reverse, col.IsReverseDirection());
+ flagArray[arrayIndex] = flag;
+ centerArray[arrayIndex] = col.center;
+ sizeArray[arrayIndex] = math.max(col.GetSize(), 0.0001f); // 念のため
+ //Debug.Log($"modify symmetry parameter only.");
+ }
+ }
+ else
+ {
+ // シンメトリーなし
+ // 既存のシンメトリーコライダーが存在する場合は削除する
+ RemoveColliderInternal(col, teamId, true);
+ //Debug.Log($"remove symmetry.");
+ }
}
+ //=========================================================================================
+ // Simulation
//=========================================================================================
///
/// シミュレーション更新前処理
/// コライダー姿勢の読み取り
///
- ///
- ///
- internal JobHandle PreSimulationUpdate(JobHandle jobHandle)
- {
- if (DataCount == 0)
- return jobHandle;
-
- var job = new PreSimulationUpdateJob()
- {
- teamDataArray = MagicaManager.Team.teamDataArray.GetNativeArray(),
- centerDataArray = MagicaManager.Team.centerDataArray.GetNativeArray(),
-
- teamIdArray = teamIdArray.GetNativeArray(),
- flagArray = flagArray.GetNativeArray(),
- centerArray = centerArray.GetNativeArray(),
- framePositions = framePositions.GetNativeArray(),
- frameRotations = frameRotations.GetNativeArray(),
- frameScales = frameScales.GetNativeArray(),
- oldFramePositions = oldFramePositions.GetNativeArray(),
- oldFrameRotations = oldFrameRotations.GetNativeArray(),
- //oldFrameScales = oldFrameScales.GetNativeArray(),
- nowPositions = nowPositions.GetNativeArray(),
- nowRotations = nowRotations.GetNativeArray(),
- oldPositions = oldPositions.GetNativeArray(),
- oldRotations = oldRotations.GetNativeArray(),
-
- transformPositionArray = MagicaManager.Bone.positionArray.GetNativeArray(),
- transformRotationArray = MagicaManager.Bone.rotationArray.GetNativeArray(),
- transformScaleArray = MagicaManager.Bone.scaleArray.GetNativeArray(),
- };
- jobHandle = job.Schedule(DataCount, 8, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct PreSimulationUpdateJob : IJobParallelFor
- {
+ internal static void SimulationPreUpdate(
+ DataChunk chunk,
// team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray centerDataArray;
-
+ ref TeamManager.TeamData tdata,
+ ref InertiaConstraint.CenterData cdata,
// collider
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- //[Unity.Collections.ReadOnly]
- public NativeArray flagArray;
- [Unity.Collections.ReadOnly]
- public NativeArray centerArray;
- [Unity.Collections.WriteOnly]
- public NativeArray framePositions;
- [Unity.Collections.WriteOnly]
- public NativeArray frameRotations;
- [Unity.Collections.WriteOnly]
- public NativeArray frameScales;
- public NativeArray oldFramePositions;
- public NativeArray oldFrameRotations;
- //[Unity.Collections.WriteOnly]
- //public NativeArray oldFrameScales;
- public NativeArray nowPositions;
- public NativeArray nowRotations;
- public NativeArray oldPositions;
- public NativeArray oldRotations;
-
- // transform (ワールド姿勢)
- [Unity.Collections.ReadOnly]
- public NativeArray transformPositionArray;
- [Unity.Collections.ReadOnly]
- public NativeArray transformRotationArray;
- [Unity.Collections.ReadOnly]
- public NativeArray transformScaleArray;
-
- public void Execute(int index)
+ ref NativeArray flagArray,
+ ref NativeArray centerArray,
+ ref NativeArray framePositions,
+ ref NativeArray frameRotations,
+ ref NativeArray frameScales,
+ ref NativeArray oldFramePositions,
+ ref NativeArray oldFrameRotations,
+ ref NativeArray nowPositions,
+ ref NativeArray nowRotations,
+ ref NativeArray oldPositions,
+ ref NativeArray oldRotations,
+ ref NativeArray mainColliderIndices,
+ // transform
+ ref NativeArray transformPositionArray,
+ ref NativeArray transformRotationArray,
+ ref NativeArray transformScaleArray,
+ ref NativeArray transformLocalPositionArray,
+ ref NativeArray transformLocalRotationArray,
+ ref NativeArray transformLocalScaleArray
+ )
+ {
+ // コライダーごと
+ //int index = tdata.colliderChunk.startIndex;
+ int index = tdata.colliderChunk.startIndex + chunk.startIndex;
+ //for (int i = 0; i < tdata.colliderChunk.dataLength; i++, index++)
+ for (int i = 0; i < chunk.dataLength; i++, index++)
{
var flag = flagArray[index];
if (flag.IsSet(Flag_Valid) == false || flag.IsSet(Flag_Enable) == false)
- return;
-
- int teamId = teamIdArray[index];
- var tdata = teamDataArray[teamId];
- if (tdata.IsProcess == false)
- return;
+ continue;
var center = centerArray[index];
int l_index = index - tdata.colliderChunk.startIndex;
int t_index = tdata.colliderTransformChunk.startIndex + l_index;
- // transform姿勢(ワールド)
- var wpos = transformPositionArray[t_index];
- var wrot = transformRotationArray[t_index];
- var wscl = transformScaleArray[t_index];
+ // ほぼ0スケールは極小スケールに変換し無効化させる
+ bool isZeroScale = false;
+ float3 pscl = transformScaleArray[t_index];
+ for (int j = 0; j < 3; j++)
+ {
+ float s = pscl[j];
+ if (s < 1e-06f && s > -1e-06f)
+ {
+ pscl[j] = 1e-06f;
+ isZeroScale = true;
+ }
+ }
+ flag.SetFlag(Flag_ScaleSuspend, isZeroScale);
- // オフセット
- wpos += math.mul(wrot, center) * wscl;
+ // コライダー姿勢(ワールド)
+ float3 wpos;
+ quaternion wrot;
+ float3 wscl;
+ if (flag.IsSet(Flag_Symmetry))
+ {
+ // Symmetry
+ int mainLocalIndex = mainColliderIndices[index];
+ int mainTransformIndex = tdata.colliderTransformChunk.startIndex + mainLocalIndex;
+ float3 lpos = transformLocalPositionArray[mainTransformIndex];
+ float3 lerot = MathUtility.ToEuler(transformLocalRotationArray[mainTransformIndex]);
+ float3 lscl = transformLocalScaleArray[mainTransformIndex];
+
+ var symmetryType = DataUtility.GetSymmetryType(flag);
+ switch (symmetryType)
+ {
+ case SymmetryType.X_Symmetry:
+ lpos.x = -lpos.x;
+ center.x = -center.x;
+ lerot.y = -lerot.y;
+ lerot.z = -lerot.z;
+ break;
+ case SymmetryType.Y_Symmetry:
+ lpos.y = -lpos.y;
+ center.y = -center.y;
+ lerot.x = -lerot.x;
+ lerot.z = -lerot.z;
+ break;
+ case SymmetryType.Z_Symmetry:
+ lpos.z = -lpos.z;
+ center.z = -center.z;
+ lerot.x = -lerot.x;
+ lerot.y = -lerot.y;
+ break;
+ case SymmetryType.XYZ_Symmetry:
+ lpos = -lpos;
+ center = -center;
+ break;
+ }
+
+ // シンメトリー先の親
+ float3 ppos = transformPositionArray[t_index];
+ quaternion prot = transformRotationArray[t_index];
+ //float3 pscl = transformScaleArray[t_index];
+
+ // マイナススケール
+ float3 sclSign = math.sign(pscl);
+ float3 sclEulerSign = 1;
+ if (pscl.x < 0 || pscl.y < 0 || pscl.z < 0)
+ sclEulerSign = sclSign * -1;
+
+ // シンメトリーコライダーの姿勢
+ wpos = MathUtility.TransformPoint(lpos, ppos, prot, pscl);
+ wrot = math.mul(prot, quaternion.Euler(math.radians(lerot * sclEulerSign)));
+ wscl = pscl * lscl;
+
+ // オフセット
+ wpos += math.mul(wrot, center * sclSign) * wscl * sclSign;
+ }
+ else
+ {
+ // Main
+ wpos = transformPositionArray[t_index];
+ wrot = transformRotationArray[t_index];
+ //wscl = transformScaleArray[t_index];
+ wscl = pscl;
+
+ // マイナススケール
+ float3 sclSign = math.sign(wscl);
+
+ // オフセット
+ wpos += math.mul(wrot, center * sclSign) * wscl * sclSign;
+ }
// 格納
framePositions[index] = wpos;
@@ -748,195 +976,104 @@ namespace MagicaCloth2
frameScales[index] = wscl;
// リセット処理
- if (tdata.IsReset || flag.IsSet(Flag_Reset))
+ if (tdata.IsReset || flag.IsSet(Flag_Reset) || isZeroScale)
{
oldFramePositions[index] = wpos;
oldFrameRotations[index] = wrot;
- //oldFrameScales[index] = lscl;
nowPositions[index] = wpos;
nowRotations[index] = wrot;
oldPositions[index] = wpos;
oldRotations[index] = wrot;
flag.SetFlag(Flag_Reset, false);
- flagArray[index] = flag;
}
- else if (tdata.IsInertiaShift)
+ else if (tdata.IsInertiaShift || tdata.IsNegativeScaleTeleport)
{
// 慣性全体シフト
- var cdata = centerDataArray[teamId];
+ var oldFramePosition = oldFramePositions[index];
+ var oldFrameRotation = oldFrameRotations[index];
+ var nowPosition = nowPositions[index];
+ var nowRotation = nowRotations[index];
+ var oldPosition = oldPositions[index];
+ var oldRotation = oldRotations[index];
- // cdata.frameComponentShiftVector : 全体シフトベクトル
- // cdata.frameComponentShiftRotation : 全体シフト回転
- // cdata.oldComponentWorldPosition : フレーム移動前のコンポーネント中心位置
-
- float3 prevFrameWorldPosition = cdata.oldComponentWorldPosition;
-
- oldFramePositions[index] = MathUtility.ShiftPosition(oldFramePositions[index], prevFrameWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
- oldFrameRotations[index] = math.mul(cdata.frameComponentShiftRotation, oldFrameRotations[index]);
-
- nowPositions[index] = MathUtility.ShiftPosition(nowPositions[index], prevFrameWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
- nowRotations[index] = math.mul(cdata.frameComponentShiftRotation, nowRotations[index]);
-
- oldPositions[index] = MathUtility.ShiftPosition(oldPositions[index], prevFrameWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
- oldRotations[index] = math.mul(cdata.frameComponentShiftRotation, oldRotations[index]);
- }
- }
- }
-
-
- ///
- /// 今回のシミュレーションステップで計算が必要なコライダーリストを作成する
- ///
- ///
- ///
- ///
- internal JobHandle CreateUpdateColliderList(int updateIndex, JobHandle jobHandle)
- {
- var sm = MagicaManager.Simulation;
- var tm = MagicaManager.Team;
-
- var job = new CreateUpdatecolliderListJob()
- {
- updateIndex = updateIndex,
- teamDataArray = tm.teamDataArray.GetNativeArray(),
-
- jobColliderCounter = sm.processingStepCollider.Counter,
- jobColliderIndexList = sm.processingStepCollider.Buffer,
- };
- jobHandle = job.Schedule(tm.TeamCount, 1, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct CreateUpdatecolliderListJob : IJobParallelFor
- {
- public int updateIndex;
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeReference jobColliderCounter;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray jobColliderIndexList;
-
- public void Execute(int teamId)
- {
- var tdata = teamDataArray[teamId];
- if (tdata.IsProcess == false)
- return;
-
- // このステップでの更新があるか判定する
- if (updateIndex >= tdata.updateCount)
- return;
-
- // このチームが参照するコライダーを登録する
- if (tdata.ColliderCount > 0)
- {
- int start = jobColliderCounter.InterlockedStartIndex(tdata.ColliderCount);
- for (int j = 0; j < tdata.ColliderCount; j++)
+ // マイナススケール
+ if (tdata.IsNegativeScaleTeleport)
{
- int index = tdata.colliderChunk.startIndex + j;
- jobColliderIndexList[start + j] = index;
+ // 本体のスケール反転に合わせてシミュレーションに影響が出ないように必要な座標系を同様に軸反転させる
+ // コライダーはセンター空間で反転させる
+ // 回転に関してはパーティクルとは異なり法線接線をスケール方向により反転させて組み直す
+
+ // センター空間軸反転用マトリックス
+ float4x4 negativeM = cdata.negativeScaleMatrix;
+
+ oldFramePosition = MathUtility.TransformPoint(oldFramePosition, negativeM);
+ oldFrameRotation = MathUtility.TransformRotation(oldFrameRotation, negativeM, tdata.negativeScaleChange);
+
+ nowPosition = MathUtility.TransformPoint(nowPosition, negativeM);
+ nowRotation = MathUtility.TransformRotation(nowRotation, negativeM, tdata.negativeScaleChange);
+
+ oldPosition = MathUtility.TransformPoint(oldPosition, negativeM);
+ oldRotation = MathUtility.TransformRotation(oldRotation, negativeM, tdata.negativeScaleChange);
}
+
+ if (tdata.IsInertiaShift)
+ {
+ // cdata.frameComponentShiftVector : 全体シフトベクトル
+ // cdata.frameComponentShiftRotation : 全体シフト回転
+ // cdata.oldComponentWorldPosition : フレーム移動前のコンポーネント中心位置
+
+ float3 prevFrameWorldPosition = cdata.oldComponentWorldPosition;
+
+ oldFramePosition = MathUtility.ShiftPosition(oldFramePosition, prevFrameWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
+ oldFrameRotation = math.mul(cdata.frameComponentShiftRotation, oldFrameRotation);
+
+ nowPosition = MathUtility.ShiftPosition(nowPosition, prevFrameWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
+ nowRotation = math.mul(cdata.frameComponentShiftRotation, nowRotation);
+
+ oldPosition = MathUtility.ShiftPosition(oldPosition, prevFrameWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
+ oldRotation = math.mul(cdata.frameComponentShiftRotation, oldRotation);
+ }
+
+ oldFramePositions[index] = oldFramePosition;
+ oldFrameRotations[index] = oldFrameRotation;
+ nowPositions[index] = nowPosition;
+ nowRotations[index] = nowRotation;
+ oldPositions[index] = oldPosition;
+ oldRotations[index] = oldRotation;
}
+
+ // フラグ書き戻し
+ flagArray[index] = flag;
}
}
- ///
- /// シミュレーションステップ前処理
- /// コライダーの更新および作業データ作成
- ///
- ///
- ///
- internal unsafe JobHandle StartSimulationStep(JobHandle jobHandle)
- {
- var tm = MagicaManager.Team;
- var sm = MagicaManager.Simulation;
-
- var job = new StartSimulationStepJob()
- {
- jobColliderIndexList = sm.processingStepCollider.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- centerDataArray = tm.centerDataArray.GetNativeArray(),
-
- teamIdArray = teamIdArray.GetNativeArray(),
- flagArray = flagArray.GetNativeArray(),
- sizeArray = sizeArray.GetNativeArray(),
- framePositions = framePositions.GetNativeArray(),
- frameRotations = frameRotations.GetNativeArray(),
- frameScales = frameScales.GetNativeArray(),
- oldFramePositions = oldFramePositions.GetNativeArray(),
- oldFrameRotations = oldFrameRotations.GetNativeArray(),
- nowPositions = nowPositions.GetNativeArray(),
- nowRotations = nowRotations.GetNativeArray(),
- oldPositions = oldPositions.GetNativeArray(),
- oldRotations = oldRotations.GetNativeArray(),
- workDataArray = workDataArray.GetNativeArray(),
- };
- jobHandle = job.Schedule(sm.processingStepCollider.GetJobSchedulePtr(), 8, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct StartSimulationStepJob : IJobParallelForDefer
- {
- [Unity.Collections.ReadOnly]
- public NativeArray jobColliderIndexList;
-
+ internal static void SimulationStartStep(
// team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray centerDataArray;
-
+ ref TeamManager.TeamData tdata,
+ ref InertiaConstraint.CenterData cdata,
// collider
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [Unity.Collections.ReadOnly]
- public NativeArray flagArray;
- [Unity.Collections.ReadOnly]
- public NativeArray sizeArray;
- [Unity.Collections.ReadOnly]
- public NativeArray framePositions;
- [Unity.Collections.ReadOnly]
- public NativeArray frameRotations;
- [Unity.Collections.ReadOnly]
- public NativeArray frameScales;
- [Unity.Collections.ReadOnly]
- public NativeArray oldFramePositions;
- [Unity.Collections.ReadOnly]
- public NativeArray oldFrameRotations;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray nowPositions;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray nowRotations;
- [NativeDisableParallelForRestriction]
- //[Unity.Collections.ReadOnly]
- public NativeArray oldPositions;
- [NativeDisableParallelForRestriction]
- //[Unity.Collections.ReadOnly]
- public NativeArray oldRotations;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray workDataArray;
-
- public void Execute(int index)
+ ref NativeArray flagArray,
+ ref NativeArray sizeArray,
+ ref NativeArray framePositions,
+ ref NativeArray frameRotations,
+ ref NativeArray frameScales,
+ ref NativeArray oldFramePositions,
+ ref NativeArray oldFrameRotations,
+ ref NativeArray nowPositions,
+ ref NativeArray nowRotations,
+ ref NativeArray oldPositions,
+ ref NativeArray oldRotations,
+ ref NativeArray workDataArray
+ )
+ {
+ // コライダーごと
+ int cindex = tdata.colliderChunk.startIndex;
+ for (int i = 0; i < tdata.colliderChunk.dataLength; i++, cindex++)
{
- // ここでのコライダーは有効であることが保証されている
- int cindex = jobColliderIndexList[index];
var flag = flagArray[cindex];
- if (flag.IsSet(Flag_Valid) == false || flag.IsSet(Flag_Enable) == false)
- return;
- int teamId = teamIdArray[cindex];
- var tdata = teamDataArray[teamId];
+ if (flag.IsSet(Flag_Valid) == false || flag.IsSet(Flag_Enable) == false || flag.IsSet(Flag_ScaleSuspend))
+ continue;
// 今回のシミュレーションステップでの姿勢を求める
float3 pos = math.lerp(oldFramePositions[cindex], framePositions[cindex], tdata.frameInterpolation);
@@ -952,7 +1089,6 @@ namespace MagicaCloth2
var oldrot = oldRotations[cindex];
// ローカル慣性シフト
- var cdata = centerDataArray[teamId];
oldpos = math.lerp(oldpos, pos, cdata.stepMoveInertiaRatio);
oldrot = math.slerp(oldrot, rot, cdata.stepRotationInertiaRatio);
oldPositions[cindex] = oldpos;
@@ -993,7 +1129,20 @@ namespace MagicaCloth2
: math.forward();
// スケール
- float scl = math.dot(math.abs(cscl), dir); // dirの軸のスケールを使用する
+ //float scl = math.dot(math.abs(cscl), dir); // dirの軸のスケールを使用する
+
+ // マイナススケール
+ float scl0 = math.dot(cscl, dir); // dirの軸のスケールを使用する
+ dir *= math.sign(scl0); // 方向反転
+ float scl = math.abs(scl0);
+
+ // 逆方向
+ if (flag.IsSet(Flag_Reverse))
+ dir = -dir;
+
+ // シンメトリーによる方向性
+ if (flag.IsSet(Flag_Symmetry) && flag.IsSet(Flag_SymmetryReverse))
+ dir = -dir;
// x = 始点半径
// y = 終点半径
@@ -1002,9 +1151,9 @@ namespace MagicaCloth2
float sr = csize.x;
float er = csize.y;
+ float length = csize.z;
// 長さ
- float length = csize.z;
float slen = alignedCenter ? length * 0.5f : 0.0f;
float elen = alignedCenter ? length * 0.5f : (length - sr);
slen = math.max(slen - sr, 0.0f);
@@ -1032,7 +1181,15 @@ namespace MagicaCloth2
else if (type == ColliderType.Plane)
{
// 押し出し法線方向をoldposに格納する
- float3 n = math.mul(rot, math.up());
+ // マイナススケール
+ float3 dir = math.up();
+ dir *= math.sign(cscl.y); // Y反転時は逆にする
+
+ // シンメトリーによる方向性
+ if (flag.IsSet(Flag_Symmetry) && flag.IsSet(Flag_SymmetryReverse))
+ dir = -dir;
+
+ float3 n = math.mul(rot, dir);
work.oldPos.c0 = n;
work.nextPos.c0 = pos;
}
@@ -1045,120 +1202,52 @@ namespace MagicaCloth2
/// シミュレーションステップ後処理
/// old姿勢の格納
///
- ///
- ///
- internal unsafe JobHandle EndSimulationStep(JobHandle jobHandle)
- {
- var sm = MagicaManager.Simulation;
-
- var job = new EndSimulationStepJob()
- {
- jobColliderIndexList = sm.processingStepCollider.Buffer,
-
- nowPositions = nowPositions.GetNativeArray(),
- nowRotations = nowRotations.GetNativeArray(),
- oldPositions = oldPositions.GetNativeArray(),
- oldRotations = oldRotations.GetNativeArray(),
- };
- jobHandle = job.Schedule(sm.processingStepCollider.GetJobSchedulePtr(), 8, jobHandle);
-
- return jobHandle;
- }
-
-
- [BurstCompile]
- struct EndSimulationStepJob : IJobParallelForDefer
- {
- [Unity.Collections.ReadOnly]
- public NativeArray jobColliderIndexList;
-
+ internal static void SimulationEndStep(
+ DataChunk chunk,
+ // team
+ ref TeamManager.TeamData tdata,
// collider
- [Unity.Collections.ReadOnly]
- public NativeArray nowPositions;
- [Unity.Collections.ReadOnly]
- public NativeArray nowRotations;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray oldPositions;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray oldRotations;
-
- public void Execute(int index)
+ ref NativeArray nowPositions,
+ ref NativeArray nowRotations,
+ ref NativeArray oldPositions,
+ ref NativeArray oldRotations
+ )
+ {
+ //int cindex = tdata.colliderChunk.startIndex;
+ int cindex = tdata.colliderChunk.startIndex + chunk.startIndex;
+ //for (int i = 0; i < tdata.colliderChunk.dataLength; i++, cindex++)
+ for (int i = 0; i < chunk.dataLength; i++, cindex++)
{
- // ここでのコライダーは有効であることが保証されている
- int cindex = jobColliderIndexList[index];
-
oldPositions[cindex] = nowPositions[cindex];
oldRotations[cindex] = nowRotations[cindex];
}
}
-
///
/// シミュレーション更新後処理
///
- ///
- ///
- internal JobHandle PostSimulationUpdate(JobHandle jobHandle)
- {
- if (DataCount == 0)
- return jobHandle;
-
- var job = new PostSimulationUpdateJob()
- {
- teamDataArray = MagicaManager.Team.teamDataArray.GetNativeArray(),
-
- teamIdArray = teamIdArray.GetNativeArray(),
- framePositions = framePositions.GetNativeArray(),
- frameRotations = frameRotations.GetNativeArray(),
- //frameScales = frameScales.GetNativeArray(),
- oldFramePositions = oldFramePositions.GetNativeArray(),
- oldFrameRotations = oldFrameRotations.GetNativeArray(),
- //oldFrameScales = oldFrameScales.GetNativeArray(),
- };
- jobHandle = job.Schedule(DataCount, 8, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct PostSimulationUpdateJob : IJobParallelFor
- {
+ internal static void SimulationPostUpdate(
// team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
-
+ ref TeamManager.TeamData tdata,
// collider
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [Unity.Collections.ReadOnly]
- public NativeArray framePositions;
- [Unity.Collections.ReadOnly]
- public NativeArray frameRotations;
- //[Unity.Collections.ReadOnly]
- //public NativeArray frameScales;
- [Unity.Collections.WriteOnly]
- public NativeArray oldFramePositions;
- [Unity.Collections.WriteOnly]
- public NativeArray oldFrameRotations;
- //[Unity.Collections.WriteOnly]
- //public NativeArray oldFrameScales;
+ ref NativeArray framePositions,
+ ref NativeArray frameRotations,
+ ref NativeArray oldFramePositions,
+ ref NativeArray oldFrameRotations
+ )
+ {
+ if (tdata.colliderCount == 0)
+ return;
+ if (tdata.IsRunning == false)
+ return;
- public void Execute(int index)
+ int cindex = tdata.colliderChunk.startIndex;
+ for (int k = 0; k < tdata.colliderChunk.dataLength; k++, cindex++)
{
- int teamId = teamIdArray[index];
- var tdata = teamDataArray[teamId];
- if (tdata.IsProcess == false)
- return;
+ // コライダー履歴更新
+ oldFramePositions[cindex] = framePositions[cindex];
+ oldFrameRotations[cindex] = frameRotations[cindex];
- if (tdata.IsRunning)
- {
- // コライダー履歴更新
- oldFramePositions[index] = framePositions[index];
- oldFrameRotations[index] = frameRotations[index];
- //oldFrameScales[index] = frameScales[index];
- }
}
}
@@ -1173,7 +1262,9 @@ namespace MagicaCloth2
}
else
{
- sb.AppendLine($"Collider Manager. Collider:{colliderSet.Count}");
+ int cnt = teamIdArray?.Count ?? 0;
+
+ sb.AppendLine($"Use:{cnt}");
sb.AppendLine($" -flagArray:{flagArray.ToSummary()}");
sb.AppendLine($" -centerArray:{centerArray.ToSummary()}");
sb.AppendLine($" -sizeArray:{sizeArray.ToSummary()}");
@@ -1186,23 +1277,36 @@ namespace MagicaCloth2
sb.AppendLine($" -nowRotations:{nowRotations.ToSummary()}");
sb.AppendLine($" -oldPositions:{oldPositions.ToSummary()}");
sb.AppendLine($" -oldRotations:{oldRotations.ToSummary()}");
+ sb.AppendLine($" -mainColliderIndices:{mainColliderIndices.ToSummary()}");
sb.AppendLine($"[Colliders]");
- int cnt = teamIdArray?.Count ?? 0;
+ int useCnt = 0;
for (int i = 0; i < cnt; i++)
{
var flag = flagArray[i];
if (flag.IsSet(Flag_Valid) == false)
continue;
+ useCnt++;
var ctype = DataUtility.GetColliderType(flag);
- sb.AppendLine($" [{i}] tid:{teamIdArray[i]}, flag:0x{flag.Value:X}, type:{ctype}, size:{sizeArray[i]}, cen:{centerArray[i]}");
+ string sym = flag.IsSet(Flag_Symmetry) ? "Symmetry" : "";
+ sb.AppendLine($" [{i}] tid:{teamIdArray[i]}, flag:0x{flag.Value:X}, type:{ctype}, size:{sizeArray[i]}, cen:{centerArray[i]}, {sym}");
}
+ sb.AppendLine($" ActiveCount:{useCnt}");
- sb.AppendLine($"[Collider Names]");
+ sb.AppendLine($"[Collider Components:{colliderSet.Count}]");
foreach (var col in colliderSet)
{
- var name = col?.name ?? "(null)";
- sb.AppendLine($" {name}");
+ if (col)
+ {
+ sb.Append($"({col.UseTeamCount}) {col.name}");
+ if (col.ActiveSymmetryMode != ColliderSymmetryMode.None)
+ {
+ sb.Append($" Symmetry:{col.ActiveSymmetryMode}");
+ }
+ sb.AppendLine();
+ }
+ else
+ sb.AppendLine($" (null!)");
}
}
sb.AppendLine();
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs.meta
index e6b939d9..a0779118 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/ColliderManager.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs
index bfa46330..fae77a9f 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs
@@ -2,16 +2,14 @@
// Copyright (c) 2023 MagicaSoft.
// https://magicasoft.jp
using System.Text;
-using Unity.Burst;
using Unity.Collections;
-using Unity.Collections.LowLevel.Unsafe;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
namespace MagicaCloth2
{
- public class SimulationManager : IManager, IValid
+ public partial class SimulationManager : IManager, IValid
{
///
/// チームID
@@ -90,13 +88,6 @@ namespace MagicaCloth2
///
public ExNativeArray collisionNormalArray;
- ///
- /// 接触中コライダーID
- /// 接触コライダーID+1が格納されているので注意!(0=なし)
- /// todo:現在未使用!
- ///
- //public ExNativeArray colliderIdArray;
-
public int ParticleCount => nextPosArray?.Count ?? 0;
//=========================================================================================
@@ -113,38 +104,6 @@ namespace MagicaCloth2
public SelfCollisionConstraint selfCollisionConstraint;
//=========================================================================================
- ///
- /// フレームもしくはステップごとに変動するリストを管理するための汎用バッファ。用途は様々
- ///
- internal ExProcessingList processingStepParticle;
- internal ExProcessingList processingStepTriangleBending;
- internal ExProcessingList processingStepEdgeCollision;
- internal ExProcessingList processingStepCollider;
- internal ExProcessingList processingStepBaseLine;
- //internal ExProcessingList processingIntList5;
- internal ExProcessingList processingStepMotionParticle;
-
- internal ExProcessingList processingSelfParticle;
- internal ExProcessingList processingSelfPointTriangle;
- internal ExProcessingList processingSelfEdgeEdge;
- internal ExProcessingList processingSelfTrianglePoint;
-
- //---------------------------------------------------------------------
- ///
- /// 汎用float3作業バッファ
- ///
- internal NativeArray tempFloat3Buffer;
-
- ///
- /// パーティクルごとのfloat3集計カウンタ(排他制御用)
- ///
- internal NativeArray countArray;
-
- ///
- /// パーティクルごとのfloat3蓄積リスト、内部は固定小数点。パーティクル数x3。(排他制御用)
- ///
- internal NativeArray sumArray;
-
///
/// ステップごとのシミュレーションの基準となる姿勢座標
/// 初期姿勢とアニメーション姿勢をAnimatinBlendRatioで補間したもの
@@ -157,6 +116,16 @@ namespace MagicaCloth2
///
public NativeArray stepBasicRotationBuffer;
+ ///
+ /// 作業用バッファ
+ ///
+ internal NativeArray tempVectorBufferA;
+ internal NativeArray tempVectorBufferB;
+ internal NativeArray tempCountBuffer;
+ internal NativeArray tempFloatBufferA;
+ internal NativeArray tempRotationBufferA;
+ internal NativeArray tempRotationBufferB;
+
///
/// ステップ実行カウンター
///
@@ -167,6 +136,11 @@ namespace MagicaCloth2
///
internal int WorkerCount => Unity.Jobs.LowLevel.Unsafe.JobsUtility.JobWorkerCount;
+ ///
+ /// 分割ジョブを適用するプロキシメッシュの頂点数
+ ///
+ internal int splitProxyMeshVertexCount = Define.System.SplitProxyMeshVertexCount;
+
bool isValid = false;
//=========================================================================================
@@ -189,7 +163,6 @@ namespace MagicaCloth2
frictionArray?.Dispose();
staticFrictionArray?.Dispose();
collisionNormalArray?.Dispose();
- //colliderIdArray?.Dispose();
teamIdArray = null;
nextPosArray = null;
@@ -206,30 +179,23 @@ namespace MagicaCloth2
frictionArray = null;
staticFrictionArray = null;
collisionNormalArray = null;
- //colliderIdArray = null;
- processingStepParticle?.Dispose();
- processingStepTriangleBending?.Dispose();
- processingStepEdgeCollision?.Dispose();
- processingStepCollider?.Dispose();
- processingStepBaseLine?.Dispose();
- //processingIntList5?.Dispose();
- processingStepMotionParticle?.Dispose();
- processingSelfParticle?.Dispose();
- processingSelfPointTriangle?.Dispose();
- processingSelfEdgeEdge?.Dispose();
- processingSelfTrianglePoint?.Dispose();
-
- if (tempFloat3Buffer.IsCreated)
- tempFloat3Buffer.Dispose();
- if (countArray.IsCreated)
- countArray.Dispose();
- if (sumArray.IsCreated)
- sumArray.Dispose();
if (stepBasicPositionBuffer.IsCreated)
stepBasicPositionBuffer.Dispose();
if (stepBasicRotationBuffer.IsCreated)
stepBasicRotationBuffer.Dispose();
+ if (tempVectorBufferA.IsCreated)
+ tempVectorBufferA.Dispose();
+ if (tempVectorBufferB.IsCreated)
+ tempVectorBufferB.Dispose();
+ if (tempCountBuffer.IsCreated)
+ tempCountBuffer.Dispose();
+ if (tempFloatBufferA.IsCreated)
+ tempFloatBufferA.Dispose();
+ if (tempRotationBufferA.IsCreated)
+ tempRotationBufferA.Dispose();
+ if (tempRotationBufferB.IsCreated)
+ tempRotationBufferB.Dispose();
distanceConstraint?.Dispose();
bendingConstraint?.Dispose();
@@ -274,21 +240,6 @@ namespace MagicaCloth2
frictionArray = new ExNativeArray(capacity);
staticFrictionArray = new ExNativeArray(capacity);
collisionNormalArray = new ExNativeArray(capacity);
- //colliderIdArray = new ExNativeArray(capacity);
-
- processingStepParticle = new ExProcessingList();
- processingStepTriangleBending = new ExProcessingList();
- processingStepEdgeCollision = new ExProcessingList();
- processingStepCollider = new ExProcessingList();
- processingStepBaseLine = new ExProcessingList();
- //processingIntList5 = new ExProcessingList();
- processingStepMotionParticle = new ExProcessingList();
- processingSelfParticle = new ExProcessingList();
- processingSelfPointTriangle = new ExProcessingList();
- processingSelfEdgeEdge = new ExProcessingList();
- processingSelfTrianglePoint = new ExProcessingList();
-
- tempFloat3Buffer = new NativeArray(capacity, Allocator.Persistent);
// 制約
distanceConstraint = new DistanceConstraint();
@@ -323,7 +274,7 @@ namespace MagicaCloth2
return;
int teamId = cprocess.TeamId;
- var proxyMesh = cprocess.ProxyMesh;
+ var proxyMesh = cprocess.ProxyMeshContainer.shareVirtualMesh;
ref var tdata = ref MagicaManager.Team.GetTeamDataRef(teamId);
int pcnt = proxyMesh.VertexCount;
@@ -342,7 +293,6 @@ namespace MagicaCloth2
frictionArray.AddRange(pcnt);
staticFrictionArray.AddRange(pcnt);
collisionNormalArray.AddRange(pcnt);
- //colliderIdArray.AddRange(pcnt);
}
///
@@ -395,7 +345,6 @@ namespace MagicaCloth2
frictionArray.Remove(c);
staticFrictionArray.Remove(c);
collisionNormalArray.Remove(c);
- //colliderIdArray.Remove(c);
tdata.particleChunk.Clear();
@@ -413,1576 +362,1050 @@ namespace MagicaCloth2
internal void WorkBufferUpdate()
{
int pcnt = ParticleCount;
- //int ecnt = MagicaManager.VMesh.EdgeCount;
- //int tcnt = MagicaManager.VMesh.TriangleCount;
- int bcnt = MagicaManager.VMesh.BaseLineCount;
- int ccnt = MagicaManager.Collider.DataCount;
- int bendCnt = bendingConstraint.DataCount;
-
- // ステップ処理パーティクル全般
- processingStepParticle.UpdateBuffer(pcnt);
-
- // ステップ処理トライアングルベンド
- processingStepTriangleBending.UpdateBuffer(bendCnt);
-
- // ステップ処理コリジョン用エッジ
- int edgeColliderCount = MagicaManager.Team.edgeColliderCollisionCount;
- processingStepEdgeCollision.UpdateBuffer(edgeColliderCount);
-
- // 処理コライダー
- processingStepCollider.UpdateBuffer(ccnt);
-
- // ステップ処理ベースライン
- processingStepBaseLine.UpdateBuffer(bcnt);
-
- // ステップ処理セルフコリジョンパーティクル
- //processingIntList5.UpdateBuffer(pcnt);
-
- // ステップ実行モーション制約パーティクル
- processingStepMotionParticle.UpdateBuffer(pcnt);
-
- // セルフコリジョン
- processingSelfParticle.UpdateBuffer(pcnt);
- processingSelfPointTriangle.UpdateBuffer(selfCollisionConstraint.PointPrimitiveCount);
- processingSelfEdgeEdge.UpdateBuffer(selfCollisionConstraint.EdgePrimitiveCount);
- processingSelfTrianglePoint.UpdateBuffer(selfCollisionConstraint.TrianglePrimitiveCount);
// 汎用作業バッファ
- tempFloat3Buffer.Resize(pcnt);
- stepBasicPositionBuffer.Resize(pcnt);
- stepBasicRotationBuffer.Resize(pcnt);
+ // 拡張時には0クリアされる
+ stepBasicPositionBuffer.MC2Resize(pcnt);
+ stepBasicRotationBuffer.MC2Resize(pcnt);
- // 加算バッファ
- countArray.Resize(pcnt);
- sumArray.Resize(pcnt * 3);
+ // 汎用バッファ
+ // 拡張時には0クリアされる
+ tempVectorBufferA.MC2Resize(pcnt);
+ tempVectorBufferB.MC2Resize(pcnt);
+ tempCountBuffer.MC2Resize(pcnt);
+ tempFloatBufferA.MC2Resize(pcnt);
+ tempRotationBufferA.MC2Resize(pcnt);
+ tempRotationBufferB.MC2Resize(pcnt);
// 制約
- angleConstraint.WorkBufferUpdate();
- colliderCollisionConstraint.WorkBufferUpdate();
selfCollisionConstraint.WorkBufferUpdate();
}
//=========================================================================================
- ///
- /// シミュレーション実行前処理
- /// -リセット
- /// -移動影響
- ///
- ///
- ///
- internal JobHandle PreSimulationUpdate(JobHandle jobHandle)
- {
- // パーティクルのリセットおよび慣性の適用
- var job = new PreSimulationUpdateJob()
- {
- teamDataArray = MagicaManager.Team.teamDataArray.GetNativeArray(),
- parameterArray = MagicaManager.Team.parameterArray.GetNativeArray(),
- centerDataArray = MagicaManager.Team.centerDataArray.GetNativeArray(),
-
- positions = MagicaManager.VMesh.positions.GetNativeArray(),
- rotations = MagicaManager.VMesh.rotations.GetNativeArray(),
- vertexDepths = MagicaManager.VMesh.vertexDepths.GetNativeArray(),
-
- teamIdArray = teamIdArray.GetNativeArray(),
- nextPosArray = nextPosArray.GetNativeArray(),
- oldPosArray = oldPosArray.GetNativeArray(),
- oldRotArray = oldRotArray.GetNativeArray(),
- basePosArray = basePosArray.GetNativeArray(),
- baseRotArray = baseRotArray.GetNativeArray(),
- oldPositionArray = oldPositionArray.GetNativeArray(),
- oldRotationArray = oldRotationArray.GetNativeArray(),
- velocityPosArray = velocityPosArray.GetNativeArray(),
- dispPosArray = dispPosArray.GetNativeArray(),
- velocityArray = velocityArray.GetNativeArray(),
- realVelocityArray = realVelocityArray.GetNativeArray(),
- frictionArray = frictionArray.GetNativeArray(),
- staticFrictionArray = staticFrictionArray.GetNativeArray(),
- collisionNormalArray = collisionNormalArray.GetNativeArray(),
- //colliderIdArray = colliderIdArray.GetNativeArray(),
- };
- jobHandle = job.Schedule(ParticleCount, 32, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct PreSimulationUpdateJob : IJobParallelFor
- {
- // team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
- [Unity.Collections.ReadOnly]
- public NativeArray centerDataArray;
-
- // vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray positions;
- [Unity.Collections.ReadOnly]
- public NativeArray rotations;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexDepths;
-
- // particle
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [Unity.Collections.WriteOnly]
- public NativeArray nextPosArray;
- public NativeArray oldPosArray;
- public NativeArray oldRotArray;
- [Unity.Collections.WriteOnly]
- public NativeArray basePosArray;
- [Unity.Collections.WriteOnly]
- public NativeArray baseRotArray;
- public NativeArray oldPositionArray;
- public NativeArray oldRotationArray;
- [Unity.Collections.WriteOnly]
- public NativeArray velocityPosArray;
- public NativeArray dispPosArray;
- [Unity.Collections.WriteOnly]
- public NativeArray velocityArray;
- public NativeArray realVelocityArray;
- [Unity.Collections.WriteOnly]
- public NativeArray frictionArray;
- [Unity.Collections.WriteOnly]
- public NativeArray staticFrictionArray;
- [Unity.Collections.WriteOnly]
- public NativeArray collisionNormalArray;
- //[Unity.Collections.WriteOnly]
- //public NativeArray colliderIdArray;
-
- // パーティクルごと
- public void Execute(int pindex)
- {
- int teamId = teamIdArray[pindex];
- if (teamId == 0)
- return;
-
- var tdata = teamDataArray[teamId];
- if (tdata.IsProcess == false)
- return;
-
- int l_index = pindex - tdata.particleChunk.startIndex;
- int vindex = tdata.proxyCommonChunk.startIndex + l_index;
-
- if (tdata.IsReset)
- {
- // リセット
- var pos = positions[vindex];
- var rot = rotations[vindex];
-
- nextPosArray[pindex] = pos;
- oldPosArray[pindex] = pos;
- oldRotArray[pindex] = rot;
- basePosArray[pindex] = pos;
- baseRotArray[pindex] = rot;
- oldPositionArray[pindex] = pos;
- oldRotationArray[pindex] = rot;
- velocityPosArray[pindex] = pos;
- dispPosArray[pindex] = pos;
- velocityArray[pindex] = 0;
- realVelocityArray[pindex] = 0;
- frictionArray[pindex] = 0;
- staticFrictionArray[pindex] = 0;
- collisionNormalArray[pindex] = 0;
- //colliderIdArray[pindex] = 0;
- }
- else if (tdata.IsInertiaShift)
- {
- // 慣性全体シフト
- var cdata = centerDataArray[teamId];
-
- // cdata.frameComponentShiftVector : 全体シフトベクトル
- // cdata.frameComponentShiftRotation : 全体シフト回転
- // cdata.oldComponentWorldPosition : フレーム移動前のコンポーネント中心位置
-
- float3 prevFrameWorldPosition = cdata.oldComponentWorldPosition;
-
- oldPosArray[pindex] = MathUtility.ShiftPosition(oldPosArray[pindex], prevFrameWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
- oldRotArray[pindex] = math.mul(cdata.frameComponentShiftRotation, oldRotArray[pindex]);
-
- oldPositionArray[pindex] = MathUtility.ShiftPosition(oldPositionArray[pindex], prevFrameWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
- oldRotationArray[pindex] = math.mul(cdata.frameComponentShiftRotation, oldRotationArray[pindex]);
-
- dispPosArray[pindex] = MathUtility.ShiftPosition(dispPosArray[pindex], prevFrameWorldPosition, cdata.frameComponentShiftVector, cdata.frameComponentShiftRotation);
-
- realVelocityArray[pindex] = math.mul(cdata.frameComponentShiftRotation, realVelocityArray[pindex]);
- }
- }
- }
-
+ // Simulation
//=========================================================================================
///
- /// クロスシミュレーションの1ステップ実行
+ /// シミュレーションメインスケジュール
///
- ///
- ///
- ///
///
///
- unsafe internal JobHandle SimulationStepUpdate(int updateCount, int updateIndex, JobHandle jobHandle)
+ internal JobHandle ClothSimulationSchedule(JobHandle jobHandle)
{
- //Debug.Log($"Step:{updateIndex}/{updateCount}");
-
var tm = MagicaManager.Team;
+ var bm = MagicaManager.Bone;
var vm = MagicaManager.VMesh;
var wm = MagicaManager.Wind;
+ var cm = MagicaManager.Collider;
+ var tim = MagicaManager.Time;
- // シミュレーションステップカウンター
- SimulationStepCount++;
+ int normalClothTeamCount = tm.batchNormalClothTeamList.Length;
+ int splitClothTeamCount = tm.batchSplitClothTeamList.Length;
+ bool useNormalClothJob = normalClothTeamCount > 0;
+ bool useSplitClothJob = splitClothTeamCount > 0;
- // ステップごとのチーム更新
- jobHandle = tm.SimulationStepTeamUpdate(updateIndex, jobHandle);
+ if (useNormalClothJob == false && useSplitClothJob == false)
+ return jobHandle;
- // 今回のステップで計算が必要な作業リストを作成する
- var clearStepCounterJob = new ClearStepCounter()
+ // 最大更新回数
+ int maxUpdateCount = tm.TeamMaxUpdateCount;
+ //Debug.Log($"TeamMaxUpdateCount:{tm.TeamMaxUpdateCount}, UseSelfPointCollision:{tm.UseSelfPointCollision}, UseSelfEdgeCollision:{tm.UseSelfEdgeCollision}");
+
+ // 利用できるワーカースレッド数
+ int workerCount = math.max(WorkerCount, 1);
+ workerCount *= 5; // 更に分割:テスト結果より
+ //Debug.Log($"workerCount:{workerCount}");
+
+ // ジョブ連結用
+ JobHandle normalClothJobHandle = new JobHandle();
+ JobHandle splitClothJobHandle = new JobHandle();
+ JobHandle selfIntersectJobHandle = new JobHandle();
+ JobHandle solverIntersectJobHandle = new JobHandle();
+
+ // ■分割シミュレーションジョブ
+ // セルフコリジョンあり、もしくはプロキシメッシュの頂点数が一定値以上のジョブ
+ // オリジナルと同様にジョブを分割し同期しながら実行する
+ // ただし最適化を行いオリジナルより軽量化している
+ if (useSplitClothJob)
{
- processingStepParticle = processingStepParticle.Counter, // ステップ実行パーティクル
- processingStepTriangleBending = processingStepTriangleBending.Counter, // ステップ実行トライアングルベンド
- processingStepEdgeCollision = processingStepEdgeCollision.Counter, // ステップ実行エッジコリジョン
- processingStepCollider = processingStepCollider.Counter, // ステップ実行コライダーリスト
- processingStepBaseLine = processingStepBaseLine.Counter, // ステップ実行ベースライン
- //processingCounter5 = processingIntList5.Counter, // (reserve)
- processingStepMotionParticle = processingStepMotionParticle.Counter, // ステップ実行モーション制約パーティクル
+ // コンタクトキューとリスト
+ selfCollisionConstraint.contactQueue.Clear();
+ selfCollisionConstraint.contactList.Clear();
+ selfCollisionConstraint.intersectQueue.Clear();
+ selfCollisionConstraint.intersectList.Clear();
- processingSelfParticle = processingSelfParticle.Counter,
- processingSelfPointTriangle = processingSelfPointTriangle.Counter,
- processingSelfEdgeEdge = processingSelfEdgeEdge.Counter,
- processingSelfTrianglePoint = processingSelfTrianglePoint.Counter,
- };
- jobHandle = clearStepCounterJob.Schedule(jobHandle);
+ // 分割ジョブ内での各種コリジョンの有無
+ bool useEdgeCollision = tm.teamStatus.Value.z > 0;
+ bool useSelfCollision = tm.teamStatus.Value.w > 0;
- var createUpdateParticleJob = new CreateUpdateParticleList()
- {
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
+ // セルフコリジョンのインターセクト解決
+ bool useIntersect = selfCollisionConstraint.IntersectCount > 0;
- stepParticleIndexCounter = processingStepParticle.Counter,
- stepParticleIndexArray = processingStepParticle.Buffer,
-
- stepBaseLineIndexCounter = processingStepBaseLine.Counter,
- stepBaseLineIndexArray = processingStepBaseLine.Buffer,
-
- stepTriangleBendIndexCounter = processingStepTriangleBending.Counter,
- stepTriangleBendIndexArray = processingStepTriangleBending.Buffer,
-
- stepEdgeCollisionIndexCounter = processingStepEdgeCollision.Counter,
- stepEdgeCollisionIndexArray = processingStepEdgeCollision.Buffer,
-
- motionParticleIndexCounter = processingStepMotionParticle.Counter,
- motionParticleIndexArray = processingStepMotionParticle.Buffer,
-
- selfParticleCounter = processingSelfParticle.Counter,
- selfParticleIndexArray = processingSelfParticle.Buffer,
- selfPointTriangleCounter = processingSelfPointTriangle.Counter,
- selfPointTriangleIndexArray = processingSelfPointTriangle.Buffer,
- selfEdgeEdgeCounter = processingSelfEdgeEdge.Counter,
- selfEdgeEdgeIndexArray = processingSelfEdgeEdge.Buffer,
- selfTrianglePointCounter = processingSelfTrianglePoint.Counter,
- selfTrianglePointIndexArray = processingSelfTrianglePoint.Buffer,
- };
- jobHandle = createUpdateParticleJob.Schedule(tm.TeamCount, 1, jobHandle);
-
- // 今回のステップで計算が必要なコライダーリストを作成する
- jobHandle = MagicaManager.Collider.CreateUpdateColliderList(updateIndex, jobHandle);
-
- // コライダーの更新
- jobHandle = MagicaManager.Collider.StartSimulationStep(jobHandle);
-
- // 速度更新、外力の影響、慣性シフト
- var startStepJob = new StartSimulationStepJob()
- {
- simulationPower = MagicaManager.Time.SimulationPower,
- simulationDeltaTime = MagicaManager.Time.SimulationDeltaTime,
-
- stepParticleIndexArray = processingStepParticle.Buffer,
-
- attributes = vm.attributes.GetNativeArray(),
- depthArray = vm.vertexDepths.GetNativeArray(),
- positions = vm.positions.GetNativeArray(),
- rotations = vm.rotations.GetNativeArray(),
- vertexRootIndices = vm.vertexRootIndices.GetNativeArray(),
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
- centerDataArray = tm.centerDataArray.GetNativeArray(),
- teamWindArray = tm.teamWindArray.GetNativeArray(),
-
- windDataArray = wm.windDataArray.GetNativeArray(),
-
- teamIdArray = teamIdArray.GetNativeArray(),
- oldPosArray = oldPosArray.GetNativeArray(),
- velocityArray = velocityArray.GetNativeArray(),
- nextPosArray = nextPosArray.GetNativeArray(),
- basePosArray = basePosArray.GetNativeArray(),
- baseRotArray = baseRotArray.GetNativeArray(),
- oldPositionArray = oldPositionArray.GetNativeArray(),
- oldRotationArray = oldRotationArray.GetNativeArray(),
- velocityPosArray = velocityPosArray.GetNativeArray(),
- frictionArray = frictionArray.GetNativeArray(),
-
- stepBasicPositionArray = stepBasicPositionBuffer,
- stepBasicRotationArray = stepBasicRotationBuffer,
- };
- jobHandle = startStepJob.Schedule(processingStepParticle.GetJobSchedulePtr(), 32, jobHandle);
-
- // 制約解決のためのステップごとの基準姿勢を計算(ベースラインから)
- var updateStepBasicPotureJob = new UpdateStepBasicPotureJob()
- {
- stepBaseLineIndexArray = processingStepBaseLine.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
-
- attributes = MagicaManager.VMesh.attributes.GetNativeArray(),
- vertexParentIndices = vm.vertexParentIndices.GetNativeArray(),
- vertexLocalPositions = vm.vertexLocalPositions.GetNativeArray(),
- vertexLocalRotations = vm.vertexLocalRotations.GetNativeArray(),
- baseLineStartDataIndices = vm.baseLineStartDataIndices.GetNativeArray(),
- baseLineDataCounts = vm.baseLineDataCounts.GetNativeArray(),
- baseLineData = vm.baseLineData.GetNativeArray(),
- //vertexToTransformRotations = vm.vertexToTransformRotations.GetNativeArray(),
-
- basePosArray = basePosArray.GetNativeArray(),
- baseRotArray = baseRotArray.GetNativeArray(),
-
- stepBasicPositionArray = stepBasicPositionBuffer,
- stepBasicRotationArray = stepBasicRotationBuffer,
- };
- jobHandle = updateStepBasicPotureJob.Schedule(processingStepBaseLine.GetJobSchedulePtr(), 2, jobHandle);
-
- // 制約の解決
- //for (int i = 0; i < 2; i++)
- {
- // 一般制約
- jobHandle = tetherConstraint.SolverConstraint(jobHandle);
- jobHandle = distanceConstraint.SolverConstraint(jobHandle);
- jobHandle = angleConstraint.SolverConstraint(jobHandle);
- jobHandle = bendingConstraint.SolverConstraint(jobHandle);
- // コライダーコリジョン
- jobHandle = colliderCollisionConstraint.SolverConstraint(jobHandle);
- // コライダー衝突後はパーティクルが乱れる可能性があるためもう一度距離制約で整える。
- // これは裏返り防止などに効果大。
- jobHandle = distanceConstraint.SolverConstraint(jobHandle);
- // モーション制約はコライダーより優先
- jobHandle = motionConstraint.SolverConstraint(jobHandle);
- // セルフコリジョンは最後
- jobHandle = selfCollisionConstraint.SolverConstraint(updateIndex, jobHandle);
- }
-
- // 座標確定
- var endStepJob = new EndSimulationStepJob()
- {
- simulationDeltaTime = MagicaManager.Time.SimulationDeltaTime,
-
- stepParticleIndexArray = processingStepParticle.Buffer,
-
- teamDataArray = tm.teamDataArray.GetNativeArray(),
- parameterArray = tm.parameterArray.GetNativeArray(),
- centerDataArray = tm.centerDataArray.GetNativeArray(),
-
- attributes = vm.attributes.GetNativeArray(),
- vertexDepths = vm.vertexDepths.GetNativeArray(),
-
- teamIdArray = teamIdArray.GetNativeArray(),
- nextPosArray = nextPosArray.GetNativeArray(),
- oldPosArray = oldPosArray.GetNativeArray(),
- velocityArray = velocityArray.GetNativeArray(),
- realVelocityArray = realVelocityArray.GetNativeArray(),
- velocityPosArray = velocityPosArray.GetNativeArray(),
- frictionArray = frictionArray.GetNativeArray(),
- staticFrictionArray = staticFrictionArray.GetNativeArray(),
- collisionNormalArray = collisionNormalArray.GetNativeArray(),
- };
- jobHandle = endStepJob.Schedule(processingStepParticle.GetJobSchedulePtr(), 32, jobHandle);
-
- // コライダーの後更新
- jobHandle = MagicaManager.Collider.EndSimulationStep(jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct ClearStepCounter : IJob
- {
- [Unity.Collections.WriteOnly]
- public NativeReference processingStepParticle;
- [Unity.Collections.WriteOnly]
- public NativeReference processingStepTriangleBending;
- [Unity.Collections.WriteOnly]
- public NativeReference processingStepEdgeCollision;
- [Unity.Collections.WriteOnly]
- public NativeReference processingStepCollider;
- [Unity.Collections.WriteOnly]
- public NativeReference processingStepBaseLine;
- //[Unity.Collections.WriteOnly]
- //public NativeReference processingCounter5;
- [Unity.Collections.WriteOnly]
- public NativeReference processingStepMotionParticle;
-
- [Unity.Collections.WriteOnly]
- public NativeReference processingSelfParticle;
- [Unity.Collections.WriteOnly]
- public NativeReference processingSelfPointTriangle;
- [Unity.Collections.WriteOnly]
- public NativeReference processingSelfEdgeEdge;
- [Unity.Collections.WriteOnly]
- public NativeReference processingSelfTrianglePoint;
-
- public void Execute()
- {
- processingStepParticle.Value = 0;
- processingStepTriangleBending.Value = 0;
- processingStepEdgeCollision.Value = 0;
- processingStepCollider.Value = 0;
- processingStepBaseLine.Value = 0;
- //processingCounter5.Value = 0;
- processingStepMotionParticle.Value = 0;
-
- processingSelfParticle.Value = 0;
- processingSelfPointTriangle.Value = 0;
- processingSelfEdgeEdge.Value = 0;
- processingSelfTrianglePoint.Value = 0;
- }
- }
-
- [BurstCompile]
- struct CreateUpdateParticleList : IJobParallelFor
- {
- // team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
-
- // buffer
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeReference stepParticleIndexCounter;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray stepParticleIndexArray;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeReference stepBaseLineIndexCounter;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray stepBaseLineIndexArray;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeReference stepTriangleBendIndexCounter;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray stepTriangleBendIndexArray;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeReference stepEdgeCollisionIndexCounter;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray stepEdgeCollisionIndexArray;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeReference motionParticleIndexCounter;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray motionParticleIndexArray;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeReference selfParticleCounter;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray selfParticleIndexArray;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeReference selfPointTriangleCounter;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray selfPointTriangleIndexArray;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeReference selfEdgeEdgeCounter;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray selfEdgeEdgeIndexArray;
-
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeReference selfTrianglePointCounter;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray selfTrianglePointIndexArray;
-
- // チームごと
- public void Execute(int teamId)
- {
- if (teamId == 0)
- return;
-
- var tdata = teamDataArray[teamId];
- if (tdata.IsProcess == false || tdata.IsRunning == false)
- return;
-
- // このステップでの更新があるか判定する
- if (tdata.IsStepRunning == false)
- return;
-
- var parameter = parameterArray[teamId];
-
- // パーティクルリスト
- int pcnt = tdata.particleChunk.dataLength;
- int pstart = tdata.particleChunk.startIndex;
- int start = stepParticleIndexCounter.InterlockedStartIndex(pcnt);
- for (int i = 0; i < pcnt; i++)
+ // プロキシメッシュをスキニングし基本姿勢を求める
+ var splitPre_A_Job = new SplitPre_A_Job()
{
- stepParticleIndexArray[start + i] = pstart + i;
- }
+ workerCount = workerCount,
- // ベースライン
- int bcnt = tdata.BaseLineCount;
- int bstart = tdata.baseLineChunk.startIndex;
- start = stepBaseLineIndexCounter.InterlockedStartIndex(bcnt);
- for (int i = 0; i < bcnt; i++)
- {
- // 上位16bit:チームID, 下位16bit:ベースラインインデックス
- uint pack = DataUtility.Pack32(teamId, bstart + i);
- stepBaseLineIndexArray[start + i] = (int)pack;
- }
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
- // トライアングルベンド
- if (parameter.triangleBendingConstraint.method != TriangleBendingConstraint.Method.None)
+ // transform
+ transformLocalToWorldMatrixArray = bm.localToWorldMatrixArray.GetNativeArray(),
+
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ localPositions = vm.localPositions.GetNativeArray(),
+ localNormals = vm.localNormals.GetNativeArray(),
+ localTangents = vm.localTangents.GetNativeArray(),
+ boneWeights = vm.boneWeights.GetNativeArray(),
+ skinBoneTransformIndices = vm.skinBoneTransformIndices.GetNativeArray(),
+ skinBoneBindPoses = vm.skinBoneBindPoses.GetNativeArray(),
+ positions = vm.positions.GetNativeArray(),
+ rotations = vm.rotations.GetNativeArray(),
+ };
+ splitClothJobHandle = splitPre_A_Job.Schedule(splitClothTeamCount * workerCount, 1, jobHandle);
+
+ // チームのセンター姿勢の決定と慣性用の移動量計算
+ var splitPre_B_Job = new SplitPre_B_Job()
{
- int bendCnt = tdata.bendingPairChunk.dataLength;
- int bendIndex = tdata.bendingPairChunk.startIndex;
- start = stepTriangleBendIndexCounter.InterlockedStartIndex(bendCnt);
- for (int i = 0; i < bendCnt; i++, bendIndex++)
+ simulationDeltaTime = MagicaManager.Time.SimulationDeltaTime,
+
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ centerDataArray = tm.centerDataArray.GetNativeArray(),
+ teamWindArray = tm.teamWindArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+
+ // wind
+ windZoneCount = wm.WindCount,
+ windDataArray = wm.windDataArray.GetNativeArray(),
+
+ // transform
+ transformPositionArray = bm.positionArray.GetNativeArray(),
+ transformRotationArray = bm.rotationArray.GetNativeArray(),
+ transformScaleArray = bm.scaleArray.GetNativeArray(),
+
+ // vmesh
+ positions = vm.positions.GetNativeArray(),
+ rotations = vm.rotations.GetNativeArray(),
+ vertexBindPoseRotations = vm.vertexBindPoseRotations.GetNativeArray(),
+
+ // inertia
+ fixedArray = inertiaConstraint.fixedArray.GetNativeArray(),
+ };
+ splitClothJobHandle = splitPre_B_Job.Schedule(splitClothTeamCount, 1, splitClothJobHandle);
+
+ // パーティクルの全体慣性およびリセットの適用
+ // コライダーのローカル姿勢を求める、および全体慣性とリセットの適用
+ var splitPre_C_Job = new SplitPre_C_Job()
+ {
+ workerCount = workerCount,
+
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ centerDataArray = tm.centerDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+
+ // transform
+ transformPositionArray = bm.positionArray.GetNativeArray(),
+ transformRotationArray = bm.rotationArray.GetNativeArray(),
+ transformScaleArray = bm.scaleArray.GetNativeArray(),
+ transformLocalPositionArray = bm.localPositionArray.GetNativeArray(),
+ transformLocalRotationArray = bm.localRotationArray.GetNativeArray(),
+ transformLocalScaleArray = bm.localScaleArray.GetNativeArray(),
+
+ // vmesh
+ positions = vm.positions.GetNativeArray(),
+ rotations = vm.rotations.GetNativeArray(),
+ vertexDepths = vm.vertexDepths.GetNativeArray(),
+
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ oldPosArray = oldPosArray.GetNativeArray(),
+ oldRotArray = oldRotArray.GetNativeArray(),
+ basePosArray = basePosArray.GetNativeArray(),
+ baseRotArray = baseRotArray.GetNativeArray(),
+ oldPositionArray = oldPositionArray.GetNativeArray(),
+ oldRotationArray = oldRotationArray.GetNativeArray(),
+ velocityPosArray = velocityPosArray.GetNativeArray(),
+ dispPosArray = dispPosArray.GetNativeArray(),
+ velocityArray = velocityArray.GetNativeArray(),
+ realVelocityArray = realVelocityArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ staticFrictionArray = staticFrictionArray.GetNativeArray(),
+ collisionNormalArray = collisionNormalArray.GetNativeArray(),
+
+ // collider
+ colliderFlagArray = cm.flagArray.GetNativeArray(),
+ colliderCenterArray = cm.centerArray.GetNativeArray(),
+ colliderFramePositions = cm.framePositions.GetNativeArray(),
+ colliderFrameRotations = cm.frameRotations.GetNativeArray(),
+ colliderFrameScales = cm.frameScales.GetNativeArray(),
+ colliderOldFramePositions = cm.oldFramePositions.GetNativeArray(),
+ colliderOldFrameRotations = cm.oldFrameRotations.GetNativeArray(),
+ colliderNowPositions = cm.nowPositions.GetNativeArray(),
+ colliderNowRotations = cm.nowRotations.GetNativeArray(),
+ colliderOldPositions = cm.oldPositions.GetNativeArray(),
+ colliderOldRotations = cm.oldRotations.GetNativeArray(),
+ colliderMainColliderIndices = cm.mainColliderIndices.GetNativeArray(),
+ };
+ splitClothJobHandle = splitPre_C_Job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
+
+ // セルフコリジョンのインターセクトバッファの生成(開始)
+ bool useIntersectJob = false;
+ if (useSelfCollision && maxUpdateCount > 0 && useIntersect)
+ {
+ // インターセクトバッファの生成
+ // インターセクトパーティクルフラグクリア
+ var selfDetectionIntersect_job = new SelfCollisionConstraint.SelfDetectionIntersectJob()
{
- uint pack = DataUtility.Pack12_20(teamId, bendIndex);
- stepTriangleBendIndexArray[start + i] = (int)pack;
- }
- }
+ workerCount = workerCount,
+ // div
+ frameIndex = Time.frameCount % Define.System.SelfCollisionIntersectDiv,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ // self collision
+ primitiveArrayB = selfCollisionConstraint.primitiveArrayB.GetNativeArray(),
+ uniformGridStartCountBuffer = selfCollisionConstraint.uniformGridStartCountBuffer.GetNativeArray(),
+ // buffer
+ intersectQueue = selfCollisionConstraint.intersectQueue.AsParallelWriter(),
+ };
+ selfIntersectJobHandle = selfDetectionIntersect_job.Schedule(splitClothTeamCount * workerCount, 1, jobHandle);
- // エッジコライダーコリジョン
- int colliderCount = tdata.ColliderCount;
- if (parameter.colliderCollisionConstraint.mode == ColliderCollisionConstraint.Mode.Edge && tdata.proxyEdgeChunk.IsValid && colliderCount > 0)
- {
- int ecnt = tdata.proxyEdgeChunk.dataLength;
- int estart = tdata.proxyEdgeChunk.startIndex;
- start = stepEdgeCollisionIndexCounter.InterlockedStartIndex(ecnt);
- for (int i = 0; i < ecnt; i++)
+ // インターセクトバッファをリストに変換
+ var selfConvertIntersectList_job = new SelfCollisionConstraint.SelfConvertIntersectListJob()
{
- stepEdgeCollisionIndexArray[start + i] = estart + i;
- }
+ intersectQueue = selfCollisionConstraint.intersectQueue,
+ intersectList = selfCollisionConstraint.intersectList,
+ };
+ selfIntersectJobHandle = selfConvertIntersectList_job.Schedule(selfIntersectJobHandle);
+ useIntersectJob = true;
}
- // モーション制約パーティクル
- if (parameter.motionConstraint.useMaxDistance || parameter.motionConstraint.useBackstop)
+ // ■ステップループ
+ for (int updateIndex = 0; updateIndex < maxUpdateCount; updateIndex++)
{
- start = motionParticleIndexCounter.InterlockedStartIndex(pcnt);
- for (int i = 0; i < pcnt; i++)
+ bool isFirstStep = updateIndex == 0;
+
+ // チーム更新
+ // コライダーの更新
+ var splitStep_A_job = new SplitStep_A_Job()
{
- motionParticleIndexArray[start + i] = pstart + i;
- }
- }
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ simulationDeltaTime = tim.SimulationDeltaTime,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ centerDataArray = tm.centerDataArray.GetNativeArray(),
+ teamWindArray = tm.teamWindArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // collider
+ colliderFlagArray = cm.flagArray.GetNativeArray(),
+ colliderSizeArray = cm.sizeArray.GetNativeArray(),
+ colliderFramePositions = cm.framePositions.GetNativeArray(),
+ colliderFrameRotations = cm.frameRotations.GetNativeArray(),
+ colliderFrameScales = cm.frameScales.GetNativeArray(),
+ colliderOldFramePositions = cm.oldFramePositions.GetNativeArray(),
+ colliderOldFrameRotations = cm.oldFrameRotations.GetNativeArray(),
+ colliderNowPositions = cm.nowPositions.GetNativeArray(),
+ colliderNowRotations = cm.nowRotations.GetNativeArray(),
+ colliderOldPositions = cm.oldPositions.GetNativeArray(),
+ colliderOldRotations = cm.oldRotations.GetNativeArray(),
+ colliderWorkDataArray = cm.workDataArray.GetNativeArray(),
+ };
+ splitClothJobHandle = splitStep_A_job.Schedule(splitClothTeamCount, 1, splitClothJobHandle);
- // セルフコリジョン
- bool useSelfEdgeEdge = tdata.flag.TestAny(TeamManager.Flag_Self_EdgeEdge, 3);
- bool useSelfPointTriangle = tdata.flag.TestAny(TeamManager.Flag_Self_PointTriangle, 3);
- bool useSelfTrianglePoint = tdata.flag.TestAny(TeamManager.Flag_Self_TrianglePoint, 3);
- if (useSelfEdgeEdge)
- {
- int ecnt = tdata.EdgeCount;
- start = selfEdgeEdgeCounter.InterlockedStartIndex(ecnt);
- for (int i = 0; i < ecnt; i++)
+ // 速度更新、外力の影響、慣性シフト
+ var splitStep_B_job = new SplitStep_B_Job()
{
- // 上位16bit:チームID, 下位16bit:Edgeインデックス
- uint pack = DataUtility.Pack32(teamId, i);
- selfEdgeEdgeIndexArray[start + i] = pack;
- }
- }
- if (useSelfPointTriangle)
- {
- start = selfPointTriangleCounter.InterlockedStartIndex(pcnt);
- for (int i = 0; i < pcnt; i++)
+ workerCount = workerCount,
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ simulationDeltaTime = tim.SimulationDeltaTime,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ centerDataArray = tm.centerDataArray.GetNativeArray(),
+ teamWindArray = tm.teamWindArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // wind
+ windZoneCount = wm.WindCount,
+ windDataArray = wm.windDataArray.GetNativeArray(),
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ depthArray = vm.vertexDepths.GetNativeArray(),
+ positions = vm.positions.GetNativeArray(),
+ rotations = vm.rotations.GetNativeArray(),
+ vertexRootIndices = vm.vertexRootIndices.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ oldPosArray = oldPosArray.GetNativeArray(),
+ basePosArray = basePosArray.GetNativeArray(),
+ baseRotArray = baseRotArray.GetNativeArray(),
+ oldPositionArray = oldPositionArray.GetNativeArray(),
+ oldRotationArray = oldRotationArray.GetNativeArray(),
+ velocityPosArray = velocityPosArray.GetNativeArray(),
+ velocityArray = velocityArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ // buffer
+ stepBasicPositionBuffer = stepBasicPositionBuffer,
+ stepBasicRotationBuffer = stepBasicRotationBuffer,
+ };
+ splitClothJobHandle = splitStep_B_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
+
+ // ベースラインの基準姿勢を計算
+ var splitStep_C_job = new SplitStep_C_Job()
{
- // 上位16bit:チームID, 下位16bit:Pointインデックス
- uint pack = DataUtility.Pack32(teamId, i);
- selfPointTriangleIndexArray[start + i] = pack;
- }
- }
- if (useSelfTrianglePoint)
- {
- int tcnt = tdata.TriangleCount;
- start = selfTrianglePointCounter.InterlockedStartIndex(tcnt);
- for (int i = 0; i < tcnt; i++)
+ workerCount = workerCount,
+ updateIndex = updateIndex,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ vertexRootIndices = vm.vertexRootIndices.GetNativeArray(),
+ vertexParentIndices = vm.vertexParentIndices.GetNativeArray(),
+ baseLineStartDataIndices = vm.baseLineStartDataIndices.GetNativeArray(),
+ baseLineDataCounts = vm.baseLineDataCounts.GetNativeArray(),
+ baseLineData = vm.baseLineData.GetNativeArray(),
+ vertexLocalPositions = vm.vertexLocalPositions.GetNativeArray(),
+ vertexLocalRotations = vm.vertexLocalRotations.GetNativeArray(),
+ // particle
+ basePosArray = basePosArray.GetNativeArray(),
+ baseRotArray = baseRotArray.GetNativeArray(),
+ // buffer
+ stepBasicPositionBuffer = stepBasicPositionBuffer,
+ stepBasicRotationBuffer = stepBasicRotationBuffer,
+ };
+ splitClothJobHandle = splitStep_C_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
+
+ // テザー
+ // 距離
+ var splitStep_D_job = new SplitStep_D_Job()
{
- // 上位16bit:チームID, 下位16bit:Triangleインデックス
- uint pack = DataUtility.Pack32(teamId, i);
- selfTrianglePointIndexArray[start + i] = pack;
- }
- }
- if (useSelfEdgeEdge || useSelfPointTriangle || useSelfTrianglePoint)
- {
- start = selfParticleCounter.InterlockedStartIndex(pcnt);
- for (int i = 0; i < pcnt; i++)
+ workerCount = workerCount,
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ centerDataArray = tm.centerDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ depthArray = vm.vertexDepths.GetNativeArray(),
+ vertexRootIndices = vm.vertexRootIndices.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ basePosArray = basePosArray.GetNativeArray(),
+ velocityPosArray = velocityPosArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ // distance
+ distanceIndexArray = distanceConstraint.indexArray.GetNativeArray(),
+ distanceDataArray = distanceConstraint.dataArray.GetNativeArray(),
+ distanceDistanceArray = distanceConstraint.distanceArray.GetNativeArray(),
+ // buffer
+ stepBasicPositionBuffer = stepBasicPositionBuffer,
+ };
+ splitClothJobHandle = splitStep_D_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
+
+ // アングル
+ var splitStep_Angle_job = new SplitStep_Angle_Job()
{
- selfParticleIndexArray[start + i] = pstart + i;
- }
- }
+ workerCount = workerCount,
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ depthArray = vm.vertexDepths.GetNativeArray(),
+ vertexRootIndices = vm.vertexRootIndices.GetNativeArray(),
+ vertexParentIndices = vm.vertexParentIndices.GetNativeArray(),
+ baseLineStartDataIndices = vm.baseLineStartDataIndices.GetNativeArray(),
+ baseLineDataCounts = vm.baseLineDataCounts.GetNativeArray(),
+ baseLineData = vm.baseLineData.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ //basePosArray = basePosArray.GetNativeArray(),
+ velocityPosArray = velocityPosArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ // distance
+ distanceIndexArray = distanceConstraint.indexArray.GetNativeArray(),
+ distanceDataArray = distanceConstraint.dataArray.GetNativeArray(),
+ distanceDistanceArray = distanceConstraint.distanceArray.GetNativeArray(),
+ // buffer
+ stepBasicPositionBuffer = stepBasicPositionBuffer,
+ stepBasicRotationBuffer = stepBasicRotationBuffer,
+ // buffer2
+ tempVectorBufferA = tempVectorBufferA,
+ tempVectorBufferB = tempVectorBufferB,
+ tempFloatBufferA = tempFloatBufferA,
+ tempRotationBufferA = tempRotationBufferA,
+ tempRotationBufferB = tempRotationBufferB,
+ };
+ splitClothJobHandle = splitStep_Angle_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
- //Debug.Log($"Step:{updateIndex}, updateParticleCount:{jobParticleIndexList.Length}");
- }
- }
-
- [BurstCompile]
- struct StartSimulationStepJob : IJobParallelForDefer
- {
- public float4 simulationPower;
- public float simulationDeltaTime;
-
- [Unity.Collections.ReadOnly]
- public NativeArray stepParticleIndexArray;
-
- // vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray depthArray;
- [Unity.Collections.ReadOnly]
- public NativeArray positions;
- [Unity.Collections.ReadOnly]
- public NativeArray rotations;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexRootIndices;
-
- // team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
- [Unity.Collections.ReadOnly]
- public NativeArray centerDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray teamWindArray;
-
- // wind
- [Unity.Collections.ReadOnly]
- public NativeArray windDataArray;
-
- // particle
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [Unity.Collections.ReadOnly]
- public NativeArray oldPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray velocityArray;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray nextPosArray;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray basePosArray;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray baseRotArray;
- [Unity.Collections.ReadOnly]
- public NativeArray oldPositionArray;
- [Unity.Collections.ReadOnly]
- public NativeArray oldRotationArray;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray velocityPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray frictionArray;
-
- // buffer
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray stepBasicPositionArray;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray stepBasicRotationArray;
-
-
- // ステップパーティクルごと
- public void Execute(int index)
- {
- int pindex = stepParticleIndexArray[index];
- int teamId = teamIdArray[pindex];
- var tdata = teamDataArray[teamId];
- int l_index = pindex - tdata.particleChunk.startIndex;
-
- // 各カテゴリのデータインデックス
- int vindex = tdata.proxyCommonChunk.startIndex + l_index;
-
- // パラメータ
- var param = parameterArray[teamId];
-
- // nextPosSwap
- var attr = attributes[vindex];
- float depth = depthArray[vindex];
- var oldPos = oldPosArray[pindex];
-
- var nextPos = oldPos;
- var velocityPos = oldPos;
-
- // 基準姿勢のステップ補間
- var oldPosition = oldPositionArray[pindex];
- var oldRotation = oldRotationArray[pindex];
- var position = positions[vindex];
- var rotation = rotations[vindex];
-
- // ベース位置補間
- float3 basePos = math.lerp(oldPosition, position, tdata.frameInterpolation);
- quaternion baseRot = math.slerp(oldRotation, rotation, tdata.frameInterpolation);
- baseRot = math.normalize(baseRot); // 必要
- basePosArray[pindex] = basePos;
- baseRotArray[pindex] = baseRot;
-
- // ステップ基本位置
- stepBasicPositionArray[pindex] = basePos;
- stepBasicRotationArray[pindex] = baseRot;
-
- // 移動パーティクル
- if (attr.IsMove() || tdata.IsSpring)
- {
- var cdata = centerDataArray[teamId];
-
- // 重量
- //float mass = MathUtility.CalcMass(depth);
-
- // 速度
- var velocity = velocityArray[pindex];
-
-#if true
- // ■ローカル慣性シフト
- // シフト量
- float3 inertiaVector = cdata.inertiaVector;
- quaternion inertiaRotation = cdata.inertiaRotation;
-
- // 慣性の深さ影響
- float inertiaDepth = param.inertiaConstraint.depthInertia * (1.0f - depth * depth); // 二次曲線
- inertiaVector = math.lerp(inertiaVector, cdata.stepVector, inertiaDepth);
- inertiaRotation = math.slerp(inertiaRotation, cdata.stepRotation, inertiaDepth);
-
- // たぶんこっちが正しい
- float3 lpos = oldPos - cdata.oldWorldPosition;
- lpos = math.mul(inertiaRotation, lpos);
- lpos += inertiaVector;
- float3 wpos = cdata.oldWorldPosition + lpos;
- var inertiaOffset = wpos - nextPos;
-
- // nextPos
- nextPos = wpos;
-
- // 速度位置も調整
- velocityPos += inertiaOffset;
-
- // 速度に慣性回転を加える
- velocity = math.mul(inertiaRotation, velocity);
-#endif
-
- // 安定化用の速度割合
- velocity *= tdata.velocityWeight;
-
- // 抵抗
- // 重力に影響させたくないので先に計算する(※通常はforce適用後に行うのが一般的)
- float damping = param.dampingCurveData.EvaluateCurveClamp01(depth);
- velocity *= math.saturate(1.0f - damping * simulationPower.z);
-
- // 外力
- float3 force = 0;
-
- // 重力
- float3 gforce = param.gravityDirection * (param.gravity * tdata.gravityRatio);
- force += gforce;
-
- // 外力
- float3 exForce = 0;
- float mass = MathUtility.CalcMass(depth);
- switch (tdata.forceMode)
+ // トライアングルベンド
+ var splitStep_Triangle_job = new SplitStep_Triangle_Job()
{
- case ClothForceMode.VelocityAdd:
- exForce = tdata.impactForce / mass;
- break;
- case ClothForceMode.VelocityAddWithoutDepth:
- exForce = tdata.impactForce;
- break;
- case ClothForceMode.VelocityChange:
- exForce = tdata.impactForce / mass;
- velocity = 0;
- break;
- case ClothForceMode.VelocityChangeWithoutDepth:
- exForce = tdata.impactForce;
- velocity = 0;
- break;
- }
- force += exForce;
+ workerCount = workerCount,
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ depthArray = vm.vertexDepths.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ // triangle bending
+ bendingTrianglePairArray = bendingConstraint.trianglePairArray.GetNativeArray(),
+ bendingRestAngleOrVolumeArray = bendingConstraint.restAngleOrVolumeArray.GetNativeArray(),
+ bendingSignOrVolumeArray = bendingConstraint.signOrVolumeArray.GetNativeArray(),
+ // buffer2
+ tempVectorBufferA = tempVectorBufferA,
+ tempCountBuffer = tempCountBuffer,
+ };
+ splitClothJobHandle = splitStep_Triangle_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
- // 風力
- force += Wind(teamId, tdata, param.wind, cdata, vindex, pindex, depth);
-
- // 外力チームスケール倍率
- force *= tdata.scaleRatio;
-
- // 速度更新
- velocity += force * simulationDeltaTime;
-
- // 予測位置更新
- nextPos += velocity * simulationDeltaTime;
- }
- else
- {
- // 固定パーティクル
- nextPos = basePos;
- velocityPos = basePos;
- }
-
- // スプリング(固定パーティクルのみ)
- if (tdata.IsSpring && attr.IsFixed())
- {
- // ノイズ用に時間を不規則にずらす
- Spring(param.springConstraint, param.normalAxis, ref nextPos, basePos, baseRot, (tdata.time + index * 49.6198f) * 2.4512f + math.csum(nextPos), tdata.scaleRatio);
- }
-
- // 速度計算用の移動前の位置
- velocityPosArray[pindex] = velocityPos;
-
- // 予測位置格納
- nextPosArray[pindex] = nextPos;
- }
-
- void Spring(in SpringConstraint.SpringConstraintParams springParams, ClothNormalAxis normalAxis, ref float3 nextPos, in float3 basePos, in quaternion baseRot, float noiseTime, float scaleRatio)
- {
- // clamp distance
- var v = nextPos - basePos;
- float3 dir = math.up();
- switch (normalAxis)
- {
- case ClothNormalAxis.Right:
- dir = math.right();
- break;
- case ClothNormalAxis.Up:
- dir = math.up();
- break;
- case ClothNormalAxis.Forward:
- dir = math.forward();
- break;
- case ClothNormalAxis.InverseRight:
- dir = -math.right();
- break;
- case ClothNormalAxis.InverseUp:
- dir = -math.up();
- break;
- case ClothNormalAxis.InverseForward:
- dir = -math.forward();
- break;
- }
- dir = math.mul(baseRot, dir);
- float limitDistance = springParams.limitDistance * scaleRatio; // スケール倍率
-
- if (limitDistance > 1e-08f)
- {
- // 球クランプ
- var len = math.length(v);
- if (len > limitDistance)
+ // トライアングルベンド集計
+ // コライダーコリジョンPoint
+ var splitStep_E_job = new SplitStep_E_Job()
{
- v *= (limitDistance / len);
- }
+ workerCount = workerCount,
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ depthArray = vm.vertexDepths.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ basePosArray = basePosArray.GetNativeArray(),
+ velocityPosArray = velocityPosArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ collisionNormalArray = collisionNormalArray.GetNativeArray(),
+ // collider
+ colliderFlagArray = cm.flagArray.GetNativeArray(),
+ colliderWorkDataArray = cm.workDataArray.GetNativeArray(),
+ // buffer2
+ tempVectorBufferA = tempVectorBufferA,
+ tempCountBuffer = tempCountBuffer,
+ };
+ splitClothJobHandle = splitStep_E_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
- // 楕円クランプ
- if (springParams.normalLimitRatio < 1.0f)
+ // コライダーコリジョンEdge
+ if (useEdgeCollision)
{
- // もっとスマートにならないか..
- float ylen = math.dot(dir, v);
- float3 vx = v - dir * ylen;
- float xlen = math.length(vx);
- float t = xlen / limitDistance;
- float y = math.cos(math.asin(t));
- y *= limitDistance * springParams.normalLimitRatio;
-
- if (math.abs(ylen) > y)
+ var splitStep_Edge_job = new SplitStep_Edge_Job()
{
- v -= dir * (math.abs(ylen) - y) * math.sign(ylen);
+ workerCount = workerCount,
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ depthArray = vm.vertexDepths.GetNativeArray(),
+ edges = vm.edges.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ // collider
+ colliderFlagArray = cm.flagArray.GetNativeArray(),
+ colliderWorkDataArray = cm.workDataArray.GetNativeArray(),
+ // buffer2
+ tempVectorBufferA = tempVectorBufferA,
+ tempVectorBufferB = tempVectorBufferB,
+ tempCountBuffer = tempCountBuffer,
+ tempFloatBufferA = tempFloatBufferA,
+ };
+ splitClothJobHandle = splitStep_Edge_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
+ }
+
+ if (useSelfCollision)
+ {
+ // ■セルフコリジョンあり
+ // コライダーコリジョンEdge集計
+ // 距離
+ // モーション
+ var splitStep_F_Self_job = new SplitStep_F_Self_Job()
+ {
+ workerCount = workerCount,
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ depthArray = vm.vertexDepths.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ basePosArray = basePosArray.GetNativeArray(),
+ baseRotArray = baseRotArray.GetNativeArray(),
+ velocityPosArray = velocityPosArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ collisionNormalArray = collisionNormalArray.GetNativeArray(),
+ // distance
+ distanceIndexArray = distanceConstraint.indexArray.GetNativeArray(),
+ distanceDataArray = distanceConstraint.dataArray.GetNativeArray(),
+ distanceDistanceArray = distanceConstraint.distanceArray.GetNativeArray(),
+ // buffer2
+ tempVectorBufferA = tempVectorBufferA,
+ tempVectorBufferB = tempVectorBufferB,
+ tempCountBuffer = tempCountBuffer,
+ tempFloatBufferA = tempFloatBufferA,
+ };
+ splitClothJobHandle = splitStep_F_Self_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
+
+ // セルフコリジョンのインターセクトバッファ更新ジョブを合流させる
+ if (isFirstStep && useIntersectJob)
+ {
+ splitClothJobHandle = JobHandle.CombineDependencies(selfIntersectJobHandle, splitClothJobHandle);
}
- }
- }
- else
- {
- v = float3.zero;
- }
- // スプリング力
- float power = springParams.springPower;
-
- // ノイズ
- if (springParams.springNoise > 0.0f)
- {
- float noise = math.sin(noiseTime); // -1.0~+1.0
- //Debug.Log(noise);
- noise *= springParams.springNoise * 0.6f; // スケーリング
- power = math.max(power + power * noise, 0.0f);
- }
-
- // スプリング適用
- v -= v * power;
- nextPos = basePos + v;
- }
-
-
- float3 Wind(int teamId, in TeamManager.TeamData tdata, in WindParams windParams, in InertiaConstraint.CenterData cdata, int vindex, int pindex, float depth)
- {
- float3 windForce = 0;
-
- // 基準ルート座標
- // (1)チームごとにずらす
- // (2)同期率によりルートラインごとにずらす
- // (3)チームの座標やパーティクルの座標は計算に入れない
- int rootIndex = vertexRootIndices[vindex];
- float3 windPos = (teamId + 1) * 4.19230645f + (rootIndex * 0.0023963f * (1.0f - windParams.synchronization) * 100);
-
- // ゾーンごとの風影響計算
- var teamWindData = teamWindArray[teamId];
- int cnt = teamWindData.ZoneCount;
- for (int i = 0; i < cnt; i++)
- {
- var windInfo = teamWindData.windZoneList[i];
- var windData = windDataArray[windInfo.windId];
- windForce += WindForceBlend(windInfo, windParams, windPos, windData.turbulence);
- }
-
-#if true
- // 移動風影響計算
- if (windParams.movingWind > 0.01f)
- {
- windForce += WindForceBlend(teamWindData.movingWind, windParams, windPos, 1.0f);
- }
-#endif
-
- //Debug.Log($"windForce:{windForce}");
-
- // その他影響
- // チーム風影響
- float influence = windParams.influence; // 0.0 ~ 2.0
-
- // 摩擦による影響
- float friction = frictionArray[pindex];
- influence *= (1.0f - friction);
-
- // 深さ影響
- float depthScale = depth * depth;
- influence *= math.lerp(1.0f, depthScale, windParams.depthWeight);
-
- // 最終影響
- windForce *= influence;
-
- //Debug.Log($"windForce:{windForce}");
-
- return windForce;
- }
-
- float3 WindForceBlend(in TeamWindInfo windInfo, in WindParams windParams, in float3 windPos, float windTurbulence)
- {
- float windMain = windInfo.main;
- if (windMain < 0.01f)
- return 0;
-
- // 風速係数
- float mainRatio = windMain / Define.System.WindBaseSpeed; // 0.0 ~
-
- // Sin波形
- var sinPos = windPos + windInfo.time * 10.0f;
- float2 sinXY = math.sin(sinPos.xy);
-
- // Noise波形
- var noisePos = windPos + windInfo.time * 2.3132f; // Sin波形との調整用
- float2 noiseXY = new float2(noise.cnoise(noisePos.xy), noise.cnoise(noisePos.yx));
- noiseXY *= 2.3f; // cnoiseは弱いので補強 2.0?
-
- // 波形ブレンド
- float2 waveXY = math.lerp(sinXY, noiseXY, windParams.blend);
-
- // 基本乱流率
- windTurbulence *= windParams.turbulence; // 0.0 ~ 2.0
-
- // 風向き
- const float rangAng = 45.0f; // 乱流角度
- var ang = math.radians(waveXY * rangAng);
- ang.y *= math.lerp(0.1f, 0.5f, windParams.blend); // 横方向は抑える。そうしないと円運動になってしまうため。0.3 - 0.5?
- ang *= windTurbulence; // 乱流率
- var rq = quaternion.Euler(ang.x, ang.y, 0.0f); // XY
- var dirq = MathUtility.AxisQuaternion(windInfo.direction);
- float3 wdir = math.forward(math.mul(dirq, rq));
-
- // 風速
- // 風速が低いと大きくなり、風速が高いと0.0になる
- float mainScale = math.saturate(1.0f - mainRatio * 1.0f);
- float mainWave = math.unlerp(-1.0f, 1.0f, waveXY.x); // 0.0 ~ 1.0
- mainWave *= mainScale * windTurbulence;
- windMain -= windMain * mainWave;
-
- // 合成
- float3 windForce = wdir * windMain;
-
- return windForce;
- }
- }
-
- ///
- /// ベースラインごとに初期姿勢を求める
- /// これは制約の解決で利用される
- /// AnimationPoseRatioが1.0ならば不要なのでスキップされる
- ///
- [BurstCompile]
- struct UpdateStepBasicPotureJob : IJobParallelForDefer
- {
- [Unity.Collections.ReadOnly]
- public NativeArray stepBaseLineIndexArray;
-
- // team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
-
- // vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexParentIndices;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexLocalPositions;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexLocalRotations;
- [Unity.Collections.ReadOnly]
- public NativeArray baseLineStartDataIndices;
- [Unity.Collections.ReadOnly]
- public NativeArray baseLineDataCounts;
- [Unity.Collections.ReadOnly]
- public NativeArray baseLineData;
- //[Unity.Collections.ReadOnly]
- //public NativeArray vertexToTransformRotations;
-
- // particle
- [Unity.Collections.ReadOnly]
- public NativeArray basePosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray baseRotArray;
-
- // buffer
- [NativeDisableParallelForRestriction]
- public NativeArray stepBasicPositionArray;
- [NativeDisableParallelForRestriction]
- public NativeArray stepBasicRotationArray;
-
- // ステップ実行ベースラインごと
- public void Execute(int index)
- {
- // チームは有効であることが保証されている
- uint pack = (uint)stepBaseLineIndexArray[index];
- int teamId = DataUtility.Unpack32Hi(pack);
- int bindex = DataUtility.Unpack32Low(pack);
-
- var tdata = teamDataArray[teamId];
-
- // アニメーションポーズ使用の有無
- // 初期姿勢の計算が不要なら抜ける
- float blendRatio = tdata.animationPoseRatio;
- //bool isBasePose = blendRatio > 0.99f;
- if (blendRatio > 0.99f)
- return;
-
- int b_datastart = tdata.baseLineDataChunk.startIndex;
- int p_start = tdata.particleChunk.startIndex;
- int v_start = tdata.proxyCommonChunk.startIndex;
- //int vt_start = tdata.proxyBoneChunk.startIndex;
-
- // チームスケール
- float3 scl = tdata.initScale * tdata.scaleRatio;
-
- int b_start = baseLineStartDataIndices[bindex];
- int b_cnt = baseLineDataCounts[bindex];
- int b_dataindex = b_start + b_datastart;
- //if (isBasePose == false)
- {
- for (int i = 0; i < b_cnt; i++, b_dataindex++)
- {
- int l_index = baseLineData[b_dataindex];
- int pindex = p_start + l_index;
- int vindex = v_start + l_index;
-
- // 親
- int p_index = vertexParentIndices[vindex];
- int p_pindex = p_index + p_start;
-
- var attr = attributes[vindex];
- //if (attr.IsMove() == false || p_index < 0)
- //{
- // // 固定もしくはアニメーションポーズを使用
- // // basePos/baseRotをそのままコピーする
- // var bpos = basePosArray[pindex];
- // var brot = baseRotArray[pindex];
-
- // stepBasicPositionArray[pindex] = bpos;
- // stepBasicRotationArray[pindex] = brot;
- //}
- //else
- if (attr.IsMove() && p_index >= 0)
+ // セルフコリジョン
+ if (isFirstStep)
{
- // 移動
- // 親から姿勢を算出する
- var lpos = vertexLocalPositions[vindex];
- var lrot = vertexLocalRotations[vindex];
- var ppos = stepBasicPositionArray[p_pindex];
- var prot = stepBasicRotationArray[p_pindex];
- stepBasicPositionArray[pindex] = math.mul(prot, lpos * scl) + ppos;
- stepBasicRotationArray[pindex] = math.mul(prot, lrot);
- }
- }
- }
+ // ■初回ステップ
+ // (チームごとPoint/Edge/Triangle3分割)
+ // プリミティブ情報更新(nextPos/oldPos,invMass,thickness,aabb)
+ // 最大プリミティブサイズ算出、グリッドサイズ算出
+ // プリミティブ用のインターセクトフラグ更新
+ var selfStep_UpdatePrimitive_job = new SelfCollisionConstraint.SelfStep_UpdatePrimitiveJob()
+ {
+ workerCount = 3,
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ oldPosArray = oldPosArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ // self collision
+ useIntersect = useIntersect,
+ primitiveArrayB = selfCollisionConstraint.primitiveArrayB.GetNativeArray(),
+ intersectFlagArray = selfCollisionConstraint.intersectFlagArray,
+ };
+ splitClothJobHandle = selfStep_UpdatePrimitive_job.Schedule(splitClothTeamCount * 3, 1, splitClothJobHandle);
- // アニメーション姿勢とブレンド
- if (blendRatio > Define.System.Epsilon)
- {
- b_dataindex = b_start + b_datastart;
- for (int i = 0; i < b_cnt; i++, b_dataindex++)
- {
- int l_index = baseLineData[b_dataindex];
- int pindex = p_start + l_index;
+ // (チームごとPoint/Edge/Triangle3分割)
+ // プリミティブのグリッド座標算出
+ // プリミティブをグリッド座標でソート
+ // グリッド情報の作成
+ var selfStep_UpdateGrid_job = new SelfCollisionConstraint.SelfStep_UpdateGridJob()
+ {
+ kindCount = 3,
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ // self collision
+ primitiveArrayB = selfCollisionConstraint.primitiveArrayB.GetNativeArray(),
+ uniformGridStartCountBuffer = selfCollisionConstraint.uniformGridStartCountBuffer.GetNativeArray(),
+ };
+ splitClothJobHandle = selfStep_UpdateGrid_job.Schedule(splitClothTeamCount * 3, 1, splitClothJobHandle);
- var bpos = basePosArray[pindex];
- var brot = baseRotArray[pindex];
+ // コンタクトバッファの生成(EdgeEdge/PointTriangle)
+ // チームごと+特殊分散
+ var selfStep_DetectionContact_job = new SelfCollisionConstraint.SelfStep_DetectionContactJob()
+ {
+ updateIndex = updateIndex,
+ workerCount = workerCount,
+ teamCount = splitClothTeamCount,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ oldPosArray = oldPosArray.GetNativeArray(),
+ // self collision
+ primitiveArrayB = selfCollisionConstraint.primitiveArrayB.GetNativeArray(),
+ uniformGridStartCountBuffer = selfCollisionConstraint.uniformGridStartCountBuffer.GetNativeArray(),
+ // buffer
+ contactQueue = selfCollisionConstraint.contactQueue.AsParallelWriter(),
+ };
+ // Self:(EdgeEdge/PointTriangle/TrianglePoint), Sync:(EdgeEdge/PointTriangle/TrianglePoint) = 6
+ splitClothJobHandle = selfStep_DetectionContact_job.Schedule(splitClothTeamCount * 6 * workerCount, 1, splitClothJobHandle);
- stepBasicPositionArray[pindex] = math.lerp(stepBasicPositionArray[pindex], bpos, blendRatio);
- stepBasicRotationArray[pindex] = math.slerp(stepBasicRotationArray[pindex], brot, blendRatio);
- //stepBasicPositionArray[pindex] = isBasePose ? bpos : math.lerp(stepBasicPositionArray[pindex], bpos, blendRatio);
- //stepBasicRotationArray[pindex] = isBasePose ? brot : math.slerp(stepBasicRotationArray[pindex], brot, blendRatio);
- }
- }
- }
- }
-
- ///
- /// ステップ終了後の座標確定処理
- ///
- [BurstCompile]
- struct EndSimulationStepJob : IJobParallelForDefer
- {
- public float simulationDeltaTime;
-
- [Unity.Collections.ReadOnly]
- public NativeArray stepParticleIndexArray;
-
- // team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
- [Unity.Collections.ReadOnly]
- public NativeArray parameterArray;
- [Unity.Collections.ReadOnly]
- public NativeArray centerDataArray;
-
- // vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [Unity.Collections.ReadOnly]
- public NativeArray vertexDepths;
-
- // particle
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [Unity.Collections.ReadOnly]
- public NativeArray nextPosArray;
- [NativeDisableParallelForRestriction]
- public NativeArray oldPosArray;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray velocityArray;
- [NativeDisableParallelForRestriction]
- [Unity.Collections.WriteOnly]
- public NativeArray realVelocityArray;
- [Unity.Collections.ReadOnly]
- public NativeArray velocityPosArray;
- [NativeDisableParallelForRestriction]
- public NativeArray frictionArray;
- [NativeDisableParallelForRestriction]
- public NativeArray staticFrictionArray;
- [Unity.Collections.ReadOnly]
- public NativeArray collisionNormalArray;
-
- // ステップ有効パーティクルごと
- public void Execute(int index)
- {
- // パーティクルは有効であることが保証されている
- int pindex = stepParticleIndexArray[index];
- int teamId = teamIdArray[pindex];
- var tdata = teamDataArray[teamId];
- var cdata = centerDataArray[teamId];
- var param = parameterArray[teamId];
-
- int pstart = tdata.particleChunk.startIndex;
- int l_index = pindex - pstart;
-
- // 各カテゴリのデータインデックス
- int vindex = tdata.proxyCommonChunk.startIndex + l_index;
-
- var attr = attributes[vindex];
- var depth = vertexDepths[vindex];
- var nextPos = nextPosArray[pindex];
- var oldPos = oldPosArray[pindex];
-
- if (attr.IsMove() || tdata.IsSpring)
- {
- // 移動パーティクル
- var velocityOldPos = velocityPosArray[pindex];
-
-#if true
- // ■摩擦
- float friction = frictionArray[pindex];
- float3 cn = collisionNormalArray[pindex];
- bool isCollision = math.lengthsq(cn) > Define.System.Epsilon; // 接触の有無
- float staticFrictionParam = param.colliderCollisionConstraint.staticFriction * tdata.scaleRatio;
- float dynamicFrictionParam = param.colliderCollisionConstraint.dynamicFriction;
-#endif
-
-#if true
- // ■静止摩擦
- float staticFriction = staticFrictionArray[pindex];
- if (isCollision && friction > 0.0f && staticFrictionParam > 0.0f)
- {
- // 接線方向の移動速度から計算する
- var v = nextPos - oldPos;
- var tanv = v - MathUtility.Project(v, cn); // 接線方向の移動ベクトル
- float tangentVelocity = math.length(tanv) / simulationDeltaTime; // 接線方向の移動速度
-
- // 静止速度以下ならば係数を上げる
- if (tangentVelocity < staticFrictionParam)
- {
- staticFriction = math.saturate(staticFriction + 0.04f); // 係数増加(0.02?)
+ // コンタクトバッファをリストに変換
+ // ここは並列化できない
+ var selfStep_ConvertContactList_job = new SelfCollisionConstraint.SelfStep_ConvertContactListJob()
+ {
+ contactQueue = selfCollisionConstraint.contactQueue,
+ contactList = selfCollisionConstraint.contactList,
+ };
+ splitClothJobHandle = selfStep_ConvertContactList_job.Schedule(splitClothJobHandle);
}
else
{
- // 接線速度に応じて係数を減少
- var vel = tangentVelocity - staticFrictionParam;
- var value = math.max(vel / 0.2f, 0.05f);
- staticFriction = math.saturate(staticFriction - value);
+ // ■2ステップ以降
+ // コンタクトバッファごと
+ // 現在のnextPos/oldPosから変位を求め衝突の有無とs/t/nなどを求める
+ // aabbは更新なし
+ var selfStep_UpdateContact_job = new SelfCollisionConstraint.SelfStep_UpdateContactJob()
+ {
+ first = updateIndex == 0,
+ //first = true,
+ contactList = selfCollisionConstraint.contactList,
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ oldPosArray = oldPosArray.GetNativeArray(),
+ // self collision
+ primitiveArrayB = selfCollisionConstraint.primitiveArrayB.GetNativeArray(),
+ };
+ splitClothJobHandle = selfStep_UpdateContact_job.Schedule(selfCollisionConstraint.contactList, 256, splitClothJobHandle);
}
- // 接線方向に位置を巻き戻す
- tanv *= staticFriction;
- nextPos -= tanv;
- velocityOldPos -= tanv;
+ // セルフコリジョン
+ // コンタクトバッファ解決(反復)
+ for (int i = 0; i < Define.System.SelfCollisionSolverIteration; i++)
+ {
+ // コンタクトバッファ解決
+ // コンタクトバッファごと
+ var selfStep_SolverContact_job = new SelfCollisionConstraint.SelfStep_SolverContactJob()
+ {
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ // self collision
+ primitiveArrayB = selfCollisionConstraint.primitiveArrayB.GetNativeArray(),
+ contactList = selfCollisionConstraint.contactList,
+ // buffer2
+ tempVectorBufferA = tempVectorBufferA,
+ tempCountBuffer = tempCountBuffer,
+ };
+ splitClothJobHandle = selfStep_SolverContact_job.Schedule(selfCollisionConstraint.contactList, 128, splitClothJobHandle);
+
+ // 集計
+ // チームごと
+ var selfStep_SumContact_job = new SelfCollisionConstraint.SelfStep_SumContactJob()
+ {
+ updateIndex = updateIndex,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ // buffer2
+ tempVectorBufferA = tempVectorBufferA,
+ tempCountBuffer = tempCountBuffer,
+ };
+ splitClothJobHandle = selfStep_SumContact_job.Schedule(splitClothTeamCount, 1, splitClothJobHandle);
+ }
+
+ // 座標確定
+ // コライダーの後更新
+ var splitStep_G_Self_job = new SplitStep_G_Self_Job()
+ {
+ workerCount = workerCount,
+ updateIndex = updateIndex,
+ simulationDeltaTime = tim.SimulationDeltaTime,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ centerDataArray = tm.centerDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ depthArray = vm.vertexDepths.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ oldPosArray = oldPosArray.GetNativeArray(),
+ velocityPosArray = velocityPosArray.GetNativeArray(),
+ velocityArray = velocityArray.GetNativeArray(),
+ realVelocityArray = realVelocityArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ staticFrictionArray = staticFrictionArray.GetNativeArray(),
+ collisionNormalArray = collisionNormalArray.GetNativeArray(),
+ // collider
+ colliderNowPositions = cm.nowPositions.GetNativeArray(),
+ colliderNowRotations = cm.nowRotations.GetNativeArray(),
+ colliderOldPositions = cm.oldPositions.GetNativeArray(),
+ colliderOldRotations = cm.oldRotations.GetNativeArray(),
+ };
+ splitClothJobHandle = splitStep_G_Self_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
}
else
{
- // 減衰
- staticFriction = math.saturate(staticFriction - 0.05f);
- }
- staticFrictionArray[pindex] = staticFriction;
-#endif
-
- // ■速度更新(m/s) ------------------------------------------
- // 速度計算用の位置から割り出す(制約ごとの速度調整用)
- float3 velocity = (nextPos - velocityOldPos) / simulationDeltaTime;
- float sqVel = math.lengthsq(velocity);
- float3 normalVelocity = sqVel > Define.System.Epsilon ? math.normalize(velocity) : 0;
-
-#if true
- // ■動摩擦
- // 衝突面との角度が大きいほど減衰が強くなる(MC1)
- if (friction > Define.System.Epsilon && isCollision && dynamicFrictionParam > 0.0f && sqVel >= Define.System.Epsilon)
- {
- //float dot = math.dot(cn, math.normalize(velocity));
- float dot = math.dot(cn, normalVelocity);
- dot = 0.5f + 0.5f * dot; // 1.0(front) - 0.5(side) - 0.0(back)
- dot *= dot; // サイドを強めに
- dot = 1.0f - dot; // 0.0(front) - 0.75(side) - 1.0(back)
- velocity -= velocity * (dot * math.saturate(friction * dynamicFrictionParam));
- }
-
- // 摩擦減衰
- friction *= Define.System.FrictionDampingRate;
- frictionArray[pindex] = friction;
-#endif
-
-#if true
- // 最大速度
- // 最大速度はある程度制限したほうが動きが良くなるので入れるべき。
- // 特に回転時の髪などの動きが柔らかくなる。
- // しかし制限しすぎるとコライダーの押し出し制度がさがるので注意。
- if (param.inertiaConstraint.particleSpeedLimit >= 0.0f)
- {
- velocity = MathUtility.ClampVector(velocity, param.inertiaConstraint.particleSpeedLimit * tdata.scaleRatio);
- }
-#endif
-#if true
- // ■遠心力加速 ---------------------------------------------
- if (cdata.angularVelocity > Define.System.Epsilon && param.inertiaConstraint.centrifualAcceleration > Define.System.Epsilon && sqVel >= Define.System.Epsilon)
- {
- // 回転中心のローカル座標
- var lpos = nextPos - cdata.nowWorldPosition;
-
- // 回転軸平面に投影
- var v = MathUtility.ProjectOnPlane(lpos, cdata.rotationAxis);
- var r = math.length(v);
- if (r > Define.System.Epsilon)
+ // ■セルフコリジョンなし
+ // コライダーコリジョンEdge集計
+ // 距離
+ // モーション
+ // 座標確定
+ // コライダーの後更新
+ var splitStep_FG_NoSelf_job = new SplitStep_FG_NoSelf_Job()
{
- float3 n = v / r;
-
- // 角速度(rad/s)
- float w = cdata.angularVelocity;
-
- // 重量(重いほど遠心力は強くなる)
- // ここでは末端に行くほど軽くする
- //float m = (1.0f - depth) * 3.0f;
- //float m = 1.0f + (1.0f - depth) * 2.0f;
- float m = 1.0f + (1.0f - depth); // fix
- //float m = 1.0f + depth * 3.0f;
- //const float m = 1;
-
- // 遠心力
- var f = m * w * w * r;
-
- // 回転方向uと速度方向が同じ場合のみ力を加える(内積による乗算)
- // 実際の物理では遠心力は紐が張った状態でなければ発生しないがこの状態を判別する方法は簡単ではない
- // そのためこのような近似で代用する
- // 回転と速度が逆方向の場合は紐が緩んでいると判断し遠心力の増強を適用しない
- float3 u = math.normalize(math.cross(cdata.rotationAxis, n));
- f *= math.saturate(math.dot(normalVelocity, u));
-
- // 遠心力を速度に加算する
- velocity += n * (f * param.inertiaConstraint.centrifualAcceleration * 0.02f);
- }
+ workerCount = workerCount,
+ updateIndex = updateIndex,
+ simulationPower = tim.SimulationPower,
+ simulationDeltaTime = tim.SimulationDeltaTime,
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ centerDataArray = tm.centerDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ depthArray = vm.vertexDepths.GetNativeArray(),
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ oldPosArray = oldPosArray.GetNativeArray(),
+ basePosArray = basePosArray.GetNativeArray(),
+ baseRotArray = baseRotArray.GetNativeArray(),
+ velocityPosArray = velocityPosArray.GetNativeArray(),
+ velocityArray = velocityArray.GetNativeArray(),
+ realVelocityArray = realVelocityArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ staticFrictionArray = staticFrictionArray.GetNativeArray(),
+ collisionNormalArray = collisionNormalArray.GetNativeArray(),
+ // collider
+ colliderNowPositions = cm.nowPositions.GetNativeArray(),
+ colliderNowRotations = cm.nowRotations.GetNativeArray(),
+ colliderOldPositions = cm.oldPositions.GetNativeArray(),
+ colliderOldRotations = cm.oldRotations.GetNativeArray(),
+ // distance
+ distanceIndexArray = distanceConstraint.indexArray.GetNativeArray(),
+ distanceDataArray = distanceConstraint.dataArray.GetNativeArray(),
+ distanceDistanceArray = distanceConstraint.distanceArray.GetNativeArray(),
+ // buffer2
+ tempVectorBufferA = tempVectorBufferA,
+ tempVectorBufferB = tempVectorBufferB,
+ tempCountBuffer = tempCountBuffer,
+ tempFloatBufferA = tempFloatBufferA,
+ };
+ splitClothJobHandle = splitStep_FG_NoSelf_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
}
-#endif
- // 安定化用の速度割合
- velocity *= tdata.velocityWeight;
-
- // 書き戻し
- velocityArray[pindex] = velocity;
}
- // 実速度
- float3 realVelocity = (nextPos - oldPos) / simulationDeltaTime;
- realVelocityArray[pindex] = realVelocity;
- //Debug.Log($"[{pindex}] realVelocity:{realVelocity}");
+ // シミュレーション後処理
+ // 表示位置の計算
+ var splitPost_DisplayPos_job = new SplitPost_DisplayPos_Job()
+ {
+ workerCount = workerCount,
+ simulationDeltaTime = MagicaManager.Time.SimulationDeltaTime,
- // 今回の予測位置を記録
- oldPosArray[pindex] = nextPos;
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ positions = vm.positions.GetNativeArray(),
+ rotations = vm.rotations.GetNativeArray(),
+ vertexRootIndices = vm.vertexRootIndices.GetNativeArray(),
+
+ // particle
+ oldPosArray = oldPosArray.GetNativeArray(),
+ oldPositionArray = oldPositionArray.GetNativeArray(),
+ oldRotationArray = oldRotationArray.GetNativeArray(),
+ dispPosArray = dispPosArray.GetNativeArray(),
+ realVelocityArray = realVelocityArray.GetNativeArray(),
+ };
+ splitClothJobHandle = splitPost_DisplayPos_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
+
+ // 並行でインターセクトの解決を行う
+ // インターセクトの結果は次のフレームで利用される
+ if (useIntersectJob)
+ {
+ // インターセクトバッファクリア
+ var self_ClearIntersect_job = new SelfCollisionConstraint.SelfClearIntersectJob()
+ {
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ // self collision
+ intersectFlagArray = selfCollisionConstraint.intersectFlagArray,
+ };
+ solverIntersectJobHandle = self_ClearIntersect_job.Schedule(splitClothTeamCount, 1, splitClothJobHandle);
+
+ // インターセクトバッファ解決
+ var self_SolverIntersect_job = new SelfCollisionConstraint.SelfSolverIntersectJob()
+ {
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ // self collision
+ intersectList = selfCollisionConstraint.intersectList,
+ // buffer
+ intersectFlagArray = selfCollisionConstraint.intersectFlagArray,
+ };
+ solverIntersectJobHandle = self_SolverIntersect_job.Schedule(selfCollisionConstraint.intersectList, 128, solverIntersectJobHandle);
+ }
+
+ // クロスシミュレーションの結果をProxyMeshへ反映させる
+ // ラインがある場合はベースラインごとに姿勢を整える
+ var splitPost_CalcProxy_job = new SplitPost_CalcProxy_Job()
+ {
+ workerCount = workerCount,
+
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
+
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ positions = vm.positions.GetNativeArray(),
+ rotations = vm.rotations.GetNativeArray(),
+ baseLineStartDataIndices = vm.baseLineStartDataIndices.GetNativeArray(),
+ baseLineDataCounts = vm.baseLineDataCounts.GetNativeArray(),
+ baseLineData = vm.baseLineData.GetNativeArray(),
+ vertexLocalPositions = vm.vertexLocalPositions.GetNativeArray(),
+ vertexLocalRotations = vm.vertexLocalRotations.GetNativeArray(),
+ vertexChildIndexArray = vm.vertexChildIndexArray.GetNativeArray(),
+ vertexChildDataArray = vm.vertexChildDataArray.GetNativeArray(),
+ baseLineFlags = vm.baseLineFlags.GetNativeArray(),
+ };
+ splitClothJobHandle = splitPost_CalcProxy_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
+
+ // トライアングルの法線接線を求める
+ var splitPost_CalcProxyTriangle_job = new SplitPost_CalcProxyTriangle_Job()
+ {
+ workerCount = workerCount,
+
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+
+ // vmesh
+ positions = vm.positions.GetNativeArray(),
+ triangles = vm.triangles.GetNativeArray(),
+ triangleNormals = vm.triangleNormals.GetNativeArray(),
+ triangleTangents = vm.triangleTangents.GetNativeArray(),
+ uvs = vm.uv.GetNativeArray(),
+ };
+ splitClothJobHandle = splitPost_CalcProxyTriangle_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
+
+ // トライアングルの法線接線から頂点の姿勢を求める
+ // BoneClothの場合は頂点姿勢から連動するトランスフォームのワールド姿勢を計算する
+ var splitPost_SumProxyTriangleAndTransform_job = new SplitPost_SumProxyTriangleAndTransform_Job()
+ {
+ workerCount = workerCount,
+
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+
+ // transform
+ transformPositionArray = bm.positionArray.GetNativeArray(),
+ transformRotationArray = bm.rotationArray.GetNativeArray(),
+
+ // vmesh
+ positions = vm.positions.GetNativeArray(),
+ rotations = vm.rotations.GetNativeArray(),
+ triangleNormals = vm.triangleNormals.GetNativeArray(),
+ triangleTangents = vm.triangleTangents.GetNativeArray(),
+ vertexToTriangles = vm.vertexToTriangles.GetNativeArray(),
+ normalAdjustmentRotations = vm.normalAdjustmentRotations.GetNativeArray(),
+ vertexToTransformRotations = vm.vertexToTransformRotations.GetNativeArray(),
+ };
+ splitClothJobHandle = splitPost_SumProxyTriangleAndTransform_job.Schedule(splitClothTeamCount * workerCount, 1, splitClothJobHandle);
+
+ // チーム更新後処理
+ // BoneClothの場合はTransformのローカル姿勢を計算する
+ // コライダー更新後処理
+ var splitPost_TeamCollider_job = new SplitPost_TeamCollider_Job()
+ {
+ simulationDeltaTime = MagicaManager.Time.SimulationDeltaTime,
+
+ // team
+ batchSelfTeamList = tm.batchSplitClothTeamList,
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ centerDataArray = tm.centerDataArray.GetNativeArray(),
+
+ // collider
+ colliderFramePositions = cm.framePositions.GetNativeArray(),
+ colliderFrameRotations = cm.frameRotations.GetNativeArray(),
+ colliderOldFramePositions = cm.oldFramePositions.GetNativeArray(),
+ colliderOldFrameRotations = cm.oldFrameRotations.GetNativeArray(),
+
+ // transform
+ transformPositionArray = bm.positionArray.GetNativeArray(),
+ transformRotationArray = bm.rotationArray.GetNativeArray(),
+ transformScaleArray = bm.scaleArray.GetNativeArray(),
+ transformLocalPositionArray = bm.localPositionArray.GetNativeArray(),
+ transformLocalRotationArray = bm.localRotationArray.GetNativeArray(),
+
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ vertexParentIndices = vm.vertexParentIndices.GetNativeArray(),
+ };
+ splitClothJobHandle = splitPost_TeamCollider_job.Schedule(splitClothTeamCount, 1, splitClothJobHandle);
+
+ // 最後にインターセクトの解決ジョブを合流
+ if (useIntersectJob)
+ {
+ splitClothJobHandle = JobHandle.CombineDependencies(splitClothJobHandle, solverIntersectJobHandle);
+ }
}
- }
- //=========================================================================================
- ///
- /// シミュレーション完了後の表示位置の計算
- /// - 未来予測
- ///
- ///
- ///
- internal JobHandle CalcDisplayPosition(JobHandle jobHandle)
- {
- // ここではproxyMeshのpositionsのみを更新する
- // rotationsは自動で計算されるため
- var job = new CalcDisplayPositionJob()
+ // ■一括シミュレーションジョブ
+ // セルフコリジョンなし、かつプロキシメッシュの頂点数が一定値未満のジョブ
+ // 1つの巨大なジョブ内ですべてを完結させる
+ if (useNormalClothJob)
{
- simulationDeltaTime = MagicaManager.Time.SimulationDeltaTime,
+ var normalJob = new SimulationNormalJob()
+ {
+ batchNormalTeamList = tm.batchNormalClothTeamList,
+ simulationPower = tim.SimulationPower,
+ simulationDeltaTime = tim.SimulationDeltaTime,
+ mappingCount = tm.MappingCount,
- teamDataArray = MagicaManager.Team.teamDataArray.GetNativeArray(),
+ // team
+ teamDataArray = tm.teamDataArray.GetNativeArray(),
+ centerDataArray = tm.centerDataArray.GetNativeArray(),
+ teamWindArray = tm.teamWindArray.GetNativeArray(),
+ parameterArray = tm.parameterArray.GetNativeArray(),
- teamIdArray = teamIdArray.GetNativeArray(),
- oldPosArray = oldPosArray.GetNativeArray(),
- realVelocityArray = realVelocityArray.GetNativeArray(),
- oldPositionArray = oldPositionArray.GetNativeArray(),
- oldRotationArray = oldRotationArray.GetNativeArray(),
- dispPosArray = dispPosArray.GetNativeArray(),
+ // wind
+ windZoneCount = wm.WindCount,
+ windDataArray = wm.windDataArray.GetNativeArray(),
- attributes = MagicaManager.VMesh.attributes.GetNativeArray(),
- positions = MagicaManager.VMesh.positions.GetNativeArray(),
- rotations = MagicaManager.VMesh.rotations.GetNativeArray(),
- };
- jobHandle = job.Schedule(ParticleCount, 32, jobHandle);
+ // transform
+ transformPositionArray = bm.positionArray.GetNativeArray(),
+ transformRotationArray = bm.rotationArray.GetNativeArray(),
+ transformScaleArray = bm.scaleArray.GetNativeArray(),
+ transformLocalToWorldMatrixArray = bm.localToWorldMatrixArray.GetNativeArray(),
+ transformLocalPositionArray = bm.localPositionArray.GetNativeArray(),
+ transformLocalRotationArray = bm.localRotationArray.GetNativeArray(),
+ transformLocalScaleArray = bm.localScaleArray.GetNativeArray(),
+
+ // vmesh
+ attributes = vm.attributes.GetNativeArray(),
+ depthArray = vm.vertexDepths.GetNativeArray(),
+ localPositions = vm.localPositions.GetNativeArray(),
+ localNormals = vm.localNormals.GetNativeArray(),
+ localTangents = vm.localTangents.GetNativeArray(),
+ boneWeights = vm.boneWeights.GetNativeArray(),
+ skinBoneTransformIndices = vm.skinBoneTransformIndices.GetNativeArray(),
+ skinBoneBindPoses = vm.skinBoneBindPoses.GetNativeArray(),
+ positions = vm.positions.GetNativeArray(),
+ rotations = vm.rotations.GetNativeArray(),
+ vertexBindPoseRotations = vm.vertexBindPoseRotations.GetNativeArray(),
+ vertexDepths = vm.vertexDepths.GetNativeArray(),
+ vertexRootIndices = vm.vertexRootIndices.GetNativeArray(),
+ vertexParentIndices = vm.vertexParentIndices.GetNativeArray(),
+ baseLineStartDataIndices = vm.baseLineStartDataIndices.GetNativeArray(),
+ baseLineDataCounts = vm.baseLineDataCounts.GetNativeArray(),
+ baseLineData = vm.baseLineData.GetNativeArray(),
+ vertexLocalPositions = vm.vertexLocalPositions.GetNativeArray(),
+ vertexLocalRotations = vm.vertexLocalRotations.GetNativeArray(),
+ vertexChildIndexArray = vm.vertexChildIndexArray.GetNativeArray(),
+ vertexChildDataArray = vm.vertexChildDataArray.GetNativeArray(),
+ baseLineFlags = vm.baseLineFlags.GetNativeArray(),
+ triangles = vm.triangles.GetNativeArray(),
+ triangleNormals = vm.triangleNormals.GetNativeArray(),
+ triangleTangents = vm.triangleTangents.GetNativeArray(),
+ uvs = vm.uv.GetNativeArray(),
+ vertexToTriangles = vm.vertexToTriangles.GetNativeArray(),
+ normalAdjustmentRotations = vm.normalAdjustmentRotations.GetNativeArray(),
+ vertexToTransformRotations = vm.vertexToTransformRotations.GetNativeArray(),
+ edges = vm.edges.GetNativeArray(),
+
+ // particle
+ nextPosArray = nextPosArray.GetNativeArray(),
+ oldPosArray = oldPosArray.GetNativeArray(),
+ oldRotArray = oldRotArray.GetNativeArray(),
+ basePosArray = basePosArray.GetNativeArray(),
+ baseRotArray = baseRotArray.GetNativeArray(),
+ oldPositionArray = oldPositionArray.GetNativeArray(),
+ oldRotationArray = oldRotationArray.GetNativeArray(),
+ velocityPosArray = velocityPosArray.GetNativeArray(),
+ dispPosArray = dispPosArray.GetNativeArray(),
+ velocityArray = velocityArray.GetNativeArray(),
+ realVelocityArray = realVelocityArray.GetNativeArray(),
+ frictionArray = frictionArray.GetNativeArray(),
+ staticFrictionArray = staticFrictionArray.GetNativeArray(),
+ collisionNormalArray = collisionNormalArray.GetNativeArray(),
+
+ // collider
+ colliderFlagArray = cm.flagArray.GetNativeArray(),
+ colliderCenterArray = cm.centerArray.GetNativeArray(),
+ colliderSizeArray = cm.sizeArray.GetNativeArray(),
+ colliderFramePositions = cm.framePositions.GetNativeArray(),
+ colliderFrameRotations = cm.frameRotations.GetNativeArray(),
+ colliderFrameScales = cm.frameScales.GetNativeArray(),
+ colliderOldFramePositions = cm.oldFramePositions.GetNativeArray(),
+ colliderOldFrameRotations = cm.oldFrameRotations.GetNativeArray(),
+ colliderNowPositions = cm.nowPositions.GetNativeArray(),
+ colliderNowRotations = cm.nowRotations.GetNativeArray(),
+ colliderOldPositions = cm.oldPositions.GetNativeArray(),
+ colliderOldRotations = cm.oldRotations.GetNativeArray(),
+ colliderWorkDataArray = cm.workDataArray.GetNativeArray(),
+ colliderMainColliderIndices = cm.mainColliderIndices.GetNativeArray(),
+
+ // inertia
+ fixedArray = inertiaConstraint.fixedArray.GetNativeArray(),
+
+ // distance
+ distanceIndexArray = distanceConstraint.indexArray.GetNativeArray(),
+ distanceDataArray = distanceConstraint.dataArray.GetNativeArray(),
+ distanceDistanceArray = distanceConstraint.distanceArray.GetNativeArray(),
+
+ // triangleBending
+ bendingTrianglePairArray = bendingConstraint.trianglePairArray.GetNativeArray(),
+ bendingRestAngleOrVolumeArray = bendingConstraint.restAngleOrVolumeArray.GetNativeArray(),
+ bendingSignOrVolumeArray = bendingConstraint.signOrVolumeArray.GetNativeArray(),
+
+ // buffer
+ stepBasicPositionBuffer = stepBasicPositionBuffer,
+ stepBasicRotationBuffer = stepBasicRotationBuffer,
+
+ // buffer2
+ tempVectorBufferA = tempVectorBufferA,
+ tempVectorBufferB = tempVectorBufferB,
+ tempCountBuffer = tempCountBuffer,
+ tempFloatBufferA = tempFloatBufferA,
+ tempRotationBufferA = tempRotationBufferA,
+ tempRotationBufferB = tempRotationBufferB,
+ };
+ normalClothJobHandle = normalJob.Schedule(normalClothTeamCount, 1, jobHandle);
+ }
+
+ // ■ジョブ連結
+ // !一括ジョブと分割ジョブを並行動作させる
+ jobHandle = JobHandle.CombineDependencies(splitClothJobHandle, normalClothJobHandle);
+
+ // マッピングメッシュの有無で分岐
+ if (MagicaManager.Team.MappingCount > 0)
+ {
+ // この2つのジョブは並列動作可能
+ // ■マッピングメッシュの頂点姿勢を連動するプロキシメッシュからスキニングして求める
+ var job1 = vm.PostMappingMeshUpdateBatchSchedule(jobHandle, workerCount);
+
+ // ■BoneClothのTransformへの書き込み
+ var job2 = bm.WriteTransformSchedule(jobHandle);
+
+ jobHandle = JobHandle.CombineDependencies(job1, job2);
+ }
+ else
+ {
+ // ■BoneClothのTransformへの書き込み
+ jobHandle = bm.WriteTransformSchedule(jobHandle);
+ }
return jobHandle;
}
- [BurstCompile]
- struct CalcDisplayPositionJob : IJobParallelFor
- {
- public float simulationDeltaTime;
-
- // team
- [Unity.Collections.ReadOnly]
- public NativeArray teamDataArray;
-
- // particle
- [Unity.Collections.ReadOnly]
- public NativeArray teamIdArray;
- [Unity.Collections.ReadOnly]
- public NativeArray oldPosArray;
- [Unity.Collections.ReadOnly]
- public NativeArray realVelocityArray;
- [Unity.Collections.WriteOnly]
- public NativeArray oldPositionArray;
- [Unity.Collections.WriteOnly]
- public NativeArray oldRotationArray;
- public NativeArray dispPosArray;
-
- // vmesh
- [Unity.Collections.ReadOnly]
- public NativeArray attributes;
- [NativeDisableParallelForRestriction]
- public NativeArray positions;
- [Unity.Collections.ReadOnly]
- public NativeArray rotations;
-
- // すべてのパーティクルごと
- public void Execute(int pindex)
- {
- int teamId = teamIdArray[pindex];
- if (teamId == 0)
- return;
-
- var tdata = teamDataArray[teamId];
- if (tdata.IsProcess == false)
- return;
-
- // ■この処理は更新に関係なく実行する
-
- int l_index = pindex - tdata.particleChunk.startIndex;
- int vindex = tdata.proxyCommonChunk.startIndex + l_index;
-
- var attr = attributes[vindex];
- //if (attr.IsInvalid())
- // return;
-
- var pos = positions[vindex];
- var rot = rotations[vindex];
-
- if (attr.IsMove() || tdata.IsSpring)
- {
- // 移動パーティクル
- var dpos = oldPosArray[pindex];
-
-#if true
- // 未来予測
- // 最終計算位置と実速度から次のステップ位置を予測し、その間のフレーム時間位置を表示位置とする
- float3 velocity = realVelocityArray[pindex] * simulationDeltaTime;
- float3 fpos = dpos + velocity;
- float interval = (tdata.nowUpdateTime + simulationDeltaTime) - tdata.oldTime;
- //float t = (tdata.time - tdata.oldTime) / interval;
- float t = interval > 0.0f ? (tdata.time - tdata.oldTime) / interval : 0.0f;
- fpos = math.lerp(dispPosArray[pindex], fpos, t);
- dpos = fpos;
-#endif
-
- // 表示位置
- var dispPos = dpos;
-
- // 表示位置を記録
- dispPosArray[pindex] = dispPos;
-
- // ブレンドウエイト
- var vpos = math.lerp(positions[vindex], dispPos, tdata.blendWeight);
-
- // vmeshに反映
- positions[vindex] = vpos;
- }
- else
- {
- // 固定パーティクル
- // 表示位置は常にオリジナル位置
- var dispPos = positions[vindex];
- dispPosArray[pindex] = dispPos;
- }
-
- // 1つ前の原点位置を記録
- if (tdata.IsRunning)
- {
- oldPositionArray[pindex] = pos;
- oldRotationArray[pindex] = rot;
- }
- }
- }
-
- //=========================================================================================
- ///
- /// tempFloat3Bufferの内容をnextPosArrayに書き戻す
- ///
- ///
- ///
- ///
- internal JobHandle FeedbackTempFloat3Buffer(in NativeList particleList, JobHandle jobHandle)
- {
- var job = new FeedbackTempPosJob()
- {
- jobParticleIndexList = particleList,
- tempFloat3Buffer = tempFloat3Buffer,
- nextPosArray = nextPosArray.GetNativeArray(),
- };
- jobHandle = job.Schedule(particleList, 32, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct FeedbackTempPosJob : IJobParallelForDefer
- {
- [Unity.Collections.ReadOnly]
- public NativeList jobParticleIndexList;
-
- [Unity.Collections.ReadOnly]
- public NativeArray tempFloat3Buffer;
-
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
-
- public void Execute(int index)
- {
- int pindex = jobParticleIndexList[index];
- nextPosArray[pindex] = tempFloat3Buffer[pindex];
- }
- }
-
- internal JobHandle FeedbackTempFloat3Buffer(in ExProcessingList processingList, JobHandle jobHandle)
- {
- return FeedbackTempFloat3Buffer(processingList.Buffer, processingList.Counter, jobHandle);
- }
-
- unsafe internal JobHandle FeedbackTempFloat3Buffer(in NativeArray particleArray, in NativeReference counter, JobHandle jobHandle)
- {
- var job = new FeedbackTempPosJob2()
- {
- particleIndexArray = particleArray,
- tempFloat3Buffer = tempFloat3Buffer,
- nextPosArray = nextPosArray.GetNativeArray(),
- };
- jobHandle = job.Schedule((int*)counter.GetUnsafePtrWithoutChecks(), 32, jobHandle);
-
- return jobHandle;
- }
-
- [BurstCompile]
- struct FeedbackTempPosJob2 : IJobParallelForDefer
- {
- [Unity.Collections.ReadOnly]
- public NativeArray particleIndexArray;
-
- [Unity.Collections.ReadOnly]
- public NativeArray tempFloat3Buffer;
-
- [NativeDisableParallelForRestriction]
- public NativeArray nextPosArray;
-
- public void Execute(int index)
- {
- int pindex = particleIndexArray[index];
- nextPosArray[pindex] = tempFloat3Buffer[pindex];
- }
- }
-
//=========================================================================================
public void InformationLog(StringBuilder allsb)
{
@@ -2020,23 +1443,15 @@ namespace MagicaCloth2
sb.Append(selfCollisionConstraint.ToString());
// 汎用バッファ
- sb.AppendLine($"[Step Buffer]");
- sb.AppendLine($" -processingStepParticle:{processingStepParticle}");
- sb.AppendLine($" -processingStepTriangleBending:{processingStepTriangleBending}");
- sb.AppendLine($" -processingStepEdgeCollision:{processingStepEdgeCollision}");
- sb.AppendLine($" -processingStepCollider:{processingStepCollider}");
- sb.AppendLine($" -processingStepBaseLine:{processingStepBaseLine}");
- sb.AppendLine($" -processingStepMotionParticle:{processingStepMotionParticle}");
- sb.AppendLine($" -processingSelfParticle:{processingSelfParticle}");
- sb.AppendLine($" -processingSelfPointTriangle:{processingSelfPointTriangle}");
- sb.AppendLine($" -processingSelfEdgeEdge:{processingSelfEdgeEdge}");
- sb.AppendLine($" -processingSelfTrianglePoint:{processingSelfTrianglePoint}");
sb.AppendLine($"[Buffer]");
- sb.AppendLine($" -tempFloat3Buffer:{(tempFloat3Buffer.IsCreated ? tempFloat3Buffer.Length : 0)}");
- sb.AppendLine($" -countArray:{(countArray.IsCreated ? countArray.Length : 0)}");
- sb.AppendLine($" -sumArray:{(sumArray.IsCreated ? sumArray.Length : 0)}");
sb.AppendLine($" -stepBasicPositionBuffer:{(stepBasicPositionBuffer.IsCreated ? stepBasicPositionBuffer.Length : 0)}");
sb.AppendLine($" -stepBasicRotationBuffer:{(stepBasicRotationBuffer.IsCreated ? stepBasicRotationBuffer.Length : 0)}");
+ sb.AppendLine($" -tempVectorBufferA:{(tempVectorBufferA.IsCreated ? tempVectorBufferA.Length : 0)}");
+ sb.AppendLine($" -tempVectorBufferB:{(tempVectorBufferB.IsCreated ? tempVectorBufferB.Length : 0)}");
+ sb.AppendLine($" -tempCountBuffer:{(tempCountBuffer.IsCreated ? tempCountBuffer.Length : 0)}");
+ sb.AppendLine($" -tempFloatBufferA:{(tempFloatBufferA.IsCreated ? tempFloatBufferA.Length : 0)}");
+ sb.AppendLine($" -tempRotationBufferA:{(tempRotationBufferA.IsCreated ? tempRotationBufferA.Length : 0)}");
+ sb.AppendLine($" -tempRotationBufferB:{(tempRotationBufferB.IsCreated ? tempRotationBufferB.Length : 0)}");
sb.AppendLine();
}
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs.meta b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs.meta
index 2b78b3e3..433b5c39 100644
--- a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs.meta
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs.meta
@@ -9,3 +9,10 @@ MonoImporter:
userData:
assetBundleName:
assetBundleVariant:
+AssetOrigin:
+ serializedVersion: 1
+ productId: 242307
+ packageName: Magica Cloth 2
+ packageVersion: 2.16.1
+ assetPath: Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManager.cs
+ uploadId: 756593
diff --git a/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerNormal.cs b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerNormal.cs
new file mode 100644
index 00000000..ed19e8f4
--- /dev/null
+++ b/Assets/External/MagicaCloth2/Scripts/Core/Manager/Simulation/SimulationManagerNormal.cs
@@ -0,0 +1,1769 @@
+// Magica Cloth 2.
+// Copyright (c) 2025 MagicaSoft.
+// https://magicasoft.jp
+using Unity.Burst;
+using Unity.Collections;
+using Unity.Collections.LowLevel.Unsafe;
+using Unity.Jobs;
+using Unity.Mathematics;
+
+namespace MagicaCloth2
+{
+ ///
+ /// Normal
+ /// セルフコリジョンなし、かつプロキシメッシュの頂点数が一定値未満のジョブ
+ /// 1つの巨大なジョブ内ですべてを完結させる
+ ///
+ public partial class SimulationManager
+ {
+ [BurstCompile]
+ unsafe struct SimulationNormalJob : IJobParallelFor
+ {
+ [Unity.Collections.ReadOnly]
+ public NativeList batchNormalTeamList;
+ public float4 simulationPower;
+ public float simulationDeltaTime;
+ public int mappingCount;
+
+ // team
+ [NativeDisableParallelForRestriction]
+ [NativeDisableContainerSafetyRestriction]
+ public NativeArray teamDataArray;
+ [NativeDisableParallelForRestriction]
+ [NativeDisableContainerSafetyRestriction]
+ public NativeArray centerDataArray;
+ [NativeDisableParallelForRestriction]
+ [NativeDisableContainerSafetyRestriction]
+ public NativeArray teamWindArray;
+ [Unity.Collections.ReadOnly]
+ public NativeArray parameterArray;
+
+ // wind
+ public int windZoneCount;
+ [Unity.Collections.ReadOnly]
+ public NativeArray windDataArray;
+
+ // transform
+ [NativeDisableParallelForRestriction]
+ [NativeDisableContainerSafetyRestriction]
+ public NativeArray transformPositionArray;
+ [NativeDisableParallelForRestriction]
+ [NativeDisableContainerSafetyRestriction]
+ public NativeArray